37
$\begingroup$

A bug or limitation in 10.0.0 affects a few of these examples; it was resolved in 10.1.0.


I am trying out Mathematica 10 on https://programming.wolframcloud.com. $PlotTheme interested me a lot because it finally produces nice plots (probably) without the need of fine tuning of every plot. However, the options are conflicting each other and there seems to be some hiding options. For example (figures available at https://www.wolframcloud.com/objects/0caeabc9-81ba-4c6c-a51d-64f06c644a40),

(* This get thick lines *)
LogPlot[{1/x, x,2x, E^x},{x,1,10},PlotTheme->{"ThickLines"}]

(* This get monochrome *)
LogPlot[{1/x, x,2x, E^x},{x,1,10},PlotTheme->{"Monochrome"}]

(* There is no monochrome or thick lines here *)
LogPlot[{1/x, x,2x, E^x},{x,1,10},PlotTheme->{"Monochrome","ThickLines"}]

As another example,

(* Didn't get open markers or monochrome, but at least get thick *)
ListPlot[{{{1,2},{2,4},{3,7},{4,9}},{{1,3},{2,4}}},PlotTheme->{"Monochrome","OpenMarkersThick"}]

(* After adding frame, markers completely changed *)
ListPlot[{{{1,2},{2,4},{3,7},{4,9}},{{1,3},{2,4}}},PlotTheme->{"Monochrome","Frame","OpenMarkersThick"}]

Is it possible to make those themes non-conflicting with each other? The theme seems perfect for me is as follows:

(1) The lines are solid, dashed, dotted, ... ("Monochrome")

(2) The lines are colored. (e.g. "VibrantColor")

(3) Framed ("Frame").

(4) Larger labels ("LargeLabels"). At best thicker lines ("ThickLines").

(5) Setting apply both to Plot and ListPlot (to put in $PlotTheme instead of tuning every plot).

But I am not able to get all of them satisfied -- once Plot looks fine, ListPlot looks ugly. Is it possible to get some non-conflicting fine tunings once and apply everywhere?

$\endgroup$
6
  • 9
    $\begingroup$ I would certainly report your difficulties to [email protected] $\endgroup$
    – chuy
    Commented Jun 30, 2014 at 15:46
  • 2
    $\begingroup$ This could be a bug, as help says it is supposed to combine them. $\endgroup$
    – Nasser
    Commented Jun 30, 2014 at 15:49
  • 1
    $\begingroup$ It is a bug in my opinion. It appears partly dependent on order, but that is not consistent. For example {"Frame","Monochrome"} works correctly but {"ThickLines","Monochrome"} does not affect line thickness and {"Monochrome","Frame"} yields neither feature. $\endgroup$
    – mfvonh
    Commented Jun 30, 2014 at 16:10
  • $\begingroup$ Thanks a lot for the comments! I added bugs tag to the post. $\endgroup$
    – Yi Wang
    Commented Jun 30, 2014 at 18:09
  • $\begingroup$ This appears to have been improved somewhat in 10.0.1; the first example appears to work. However the other examples are still broken. $\endgroup$
    – Mr.Wizard
    Commented Sep 17, 2014 at 16:18

2 Answers 2

29
$\begingroup$

The details of the styles associated with various themes can be accessed using the function ResolvePlotThemes in the Charting context.

For example:

Grid[{#, Column@(Charting`ResolvePlotTheme[#, ListPlot] /. 
   HoldPattern[PlotMarkers -> _] :>  Sequence[])} & /@ {"Monochrome", "Frame", "Vibrant"}, 
   Dividers -> All]  (* removed the part related to PlotMarkers to save space *)

enter image description here

Similarly, for the themes "ThickLines" and "OpenMarkersThick"

 Grid[{#, Column@(Charting`ResolvePlotTheme[#, ListPlot] /. 
      HoldPattern[PlotMarkers -> _] :> Sequence[])} & /@ 
                     {"ThickLines", "OpenMarkersThick"}, 
       Dividers -> All]

enter image description here

So ...

(1) Depending on the order in which the themes appear on the RHS of PlotTheme->_ the conflicts are resolved in favor of earlier (or later ?) ones, that is, later (earlier ?) appearances of a given option are simply ignored.

(2) However, you can mix/match the relevant styling pieces from various themes. For example:

pltstylm = "DefaultPlotStyle" /. 
        (Method /. Charting`ResolvePlotTheme["Monochrome", ListLinePlot]);
pltstylv = "DefaultPlotStyle" /. 
         (Method /.  Charting`ResolvePlotTheme["Vibrant", ListLinePlot]);
pmrkrs = PlotMarkers /. Charting`ResolvePlotTheme["OpenMarkersThick", ListLinePlot];
frm = Frame /. Charting`ResolvePlotTheme["Frame", ListLinePlot];
frmstyl =  FrameStyle /. Charting`ResolvePlotTheme["Frame", ListLinePlot];
grdlnsstyl =  GridLinesStyle /.  Charting`ResolvePlotTheme["Monochrome", ListLinePlot];

ListPlot[{{{1, 2}, {2, 4}, {3, 7}, {4, 9}}, {{1, 3}, {2, 4}}},
    PlotStyle->pltstylv, PlotMarkers->pmrkrs,Frame->frm,Joined->True,
    FrameStyle->frmstyl,GridLines->Automatic,
    GridLinesStyle->grdlnsstyl, ImageSize ->700]

enter image description here

ListPlot[{{{1, 2}, {2, 4}, {3, 7}, {4, 9}}, {{1, 3}, {2, 4}}},
    PlotStyle->pltstylm, PlotMarkers->pmrkrs,Frame->frm,Joined->True,
    FrameStyle->frmstyl, GridLines->Automatic,GridLinesStyle->grdlnsstyl,
    ImageSize ->700]

enter image description here

 dashedVbrnt = Join[pltstylm,Rest@pltstylm];
 dashedVbrnt[[All, 1]] = pltstylv[[All, 1]];  
 Plot[Evaluate@Table[BesselJ[n, x], {n, 5}], {x, 0, 10}, ImageSize ->400, 
    PlotStyle -> dashedVbrnt, PlotTheme -> "Detailed"] 

enter image description here

ListPlot[Table[BesselJ[n, x], {n, 5}, {x, 0, 10,.3}], Filling->Axis,
   ImageSize ->500, PlotStyle ->dashedVbrnt, PlotMarkers->pmrkrs, Joined->True,
   PlotTheme ->"Detailed"]

enter image description here

$\endgroup$
16
$\begingroup$

The present state of affairs

The kind of manual manipulation demonstrated by kglr should theoretically not be necessary. There may have been some problems in the initial version 10 release but in either 10.0.2 or 10.1.0 many Themes already combine correctly. Emulating his penultimate example:

Plot[Evaluate@Table[BesselJ[n, x], {n, 5}], {x, 0, 10}, ImageSize -> 400, 
 PlotTheme -> {"Monochrome", "VibrantColor", "Detailed"}]

enter image description here

The last example doesn't work out so well as "Monochrome" dominates the plot:

ListLinePlot[Table[BesselJ[n, x], {n, 5}, {x, 0, 10, .3}], Filling -> Axis, 
 ImageSize -> 500, 
 PlotTheme -> {"Detailed", "Monochrome", "OpenMarkersThick", "VibrantColor"}]

enter image description here

Low-level PlotTheme definitions

To find out what went wrong with "Monochrome" we can look at its actual definition as I detailed in the Advanced method section of Is it possible to define a new PlotTheme?. First load step, then:

Defer @@ step @ System`PlotThemeDump`resolvePlotTheme["Monochrome", "ListLinePlot"]
Themes`SetWeight[
 Join[{AxesStyle -> System`PlotThemeDump`monoColor, 
   BaseStyle -> System`PlotThemeDump`monoColor, 
   FrameStyle -> System`PlotThemeDump`monoColor, 
   FrameTicksStyle -> System`PlotThemeDump`monoColor, 
   GridLinesStyle -> 
    Directive[System`PlotThemeDump`monoColor, AbsoluteThickness[1], 
     AbsoluteDashing[{1, 2}]], LabelStyle -> System`PlotThemeDump`monoFont, 
   "DefaultThickness" -> Directive[CapForm["Butt"], AbsoluteThickness[1.6]], 
   "DefaultColor" -> System`PlotThemeDump`monoColor, 
   "DefaultDashing" -> {AbsoluteDashing[{}], AbsoluteDashing[{6, 2}], 
     AbsoluteDashing[{2, 2}], AbsoluteDashing[{6, 2, 2, 2}], AbsoluteDashing[{12, 2}], 
     AbsoluteDashing[{12, 2, 2, 2, 2, 2}], AbsoluteDashing[{24, 2, 8, 2}], 
     AbsoluteDashing[{24, 2, 2, 2}]}, TicksStyle -> System`PlotThemeDump`monoColor}, 
  System`PlotThemeDump`resolvePlotTheme["PlotMarkers", 
   "ListLinePlot"]], System`PlotThemeDump`$MonochromeWeight]

Of note:

  • Among other things the BaseStyle option is being set;
  • The Theme options are given a weight of System`PlotThemeDump`$MonochromeWeight

BaseStyle precedence

BaseStyle takes precedence over the method used by "VibrantColor" (which is to set the value of System`PlotThemeDump`$ThemeColorIndexed as can be seen from viewing its definition). Therefore we can prevent that problem by setting BaseStyle -> {} as user options take further precedence:

ListLinePlot[Table[BesselJ[n, x], {n, 5}, {x, 0, 10, .3}], Filling -> Axis, 
 ImageSize -> 500, 
 PlotTheme -> {"Detailed", "Monochrome", "OpenMarkersThick", "VibrantColor"}, 
 BaseStyle -> {}]

enter image description here

SetWeight precedence

The plot markers are still wrong however. This is because System`PlotThemeDump`$MonochromeWeight is higher than System`PlotThemeDump`$ComponentWeight (used by most other Themes) and this gives it priority. If we momentarily lower that value with Block we finally get the target styling. :

Block[{System`PlotThemeDump`$MonochromeWeight = 0.4},
 ListLinePlot[Table[BesselJ[n, x], {n, 5}, {x, 0, 10, .3}], Filling -> Axis, 
  ImageSize -> 500, 
  PlotTheme -> {"Detailed", "Monochrome", "OpenMarkersThick", "VibrantColor"}, 
  BaseStyle -> {}
 ]
]

enter image description here

Customization

For future use it would be better to define a new Theme with only the dashing we want:

System`PlotThemeDump`resolvePlotTheme["monoDash", "Plot" | "ListPlot" | "ListLinePlot"] :=
  Themes`SetWeight[{"DefaultDashing" -> {AbsoluteDashing[{}], AbsoluteDashing[{6, 2}], 
     AbsoluteDashing[{2, 2}], AbsoluteDashing[{6, 2, 2, 2}], AbsoluteDashing[{12, 2}], 
     AbsoluteDashing[{12, 2, 2, 2, 2, 2}], AbsoluteDashing[{24, 2, 8, 2}], 
     AbsoluteDashing[{24, 2, 2, 2}]}}, System`PlotThemeDump`$ComponentWeight]

Now we can use it with other Themes with a weight of $ComponentWeight and it just works:

ListLinePlot[Table[BesselJ[n, x], {n, 5}, {x, 0, 10, .3}], Filling -> Axis, 
 ImageSize -> 500, 
 PlotTheme -> {"Detailed", "OpenMarkersThick", "VibrantColor", "monoDash"}]

enter image description here

$\endgroup$
6
  • 1
    $\begingroup$ Is there a way to use this to give some lines lower opacity? Changing monoDash to do "DefaultOpacity" -> {Opacity[0.5] seems to have no effect $\endgroup$ Commented May 4, 2017 at 16:43
  • $\begingroup$ @Yaroslav I'm not sure I understand. You want different opacities specified within the Theme itself? $\endgroup$
    – Mr.Wizard
    Commented May 11, 2017 at 22:51
  • $\begingroup$ Yes, I basically wanted to have first 5 plots series to be standard style, and remaining to be thick and semi-transparent $\endgroup$ Commented May 11, 2017 at 23:05
  • $\begingroup$ @Yaroslav Here is a first attempt: System`PlotThemeDump`resolvePlotTheme["Test", "Plot" | "ListPlot" | "ListLinePlot"] := Themes`SetWeight[{PlotStyle -> Join[ColorData[97] ~Array~ 5, Table[Opacity[0.5, Gray], {20}]]}, Themes`$ColorWeight]; Test: Plot[{1 x, 2 x, 3 x, 4 x, 5 x, 6 x, 7 x, 8 x, 9 x, 10 x, 11 x}, {x, 0, 5}, PlotTheme -> "Test"] -- is that the kind of result you want? -- sorry, I forgot the "thick" part; try Table[Directive[Thickness[0.01], Opacity[0.5, Gray]], {20}] instead. $\endgroup$
    – Mr.Wizard
    Commented May 11, 2017 at 23:11
  • 1
    $\begingroup$ @Yaroslav please try System`PlotThemeDump`resolvePlotTheme["Test", "Plot" | "ListPlot" | "ListLinePlot"] := Themes`SetWeight[{PlotStyle -> Join[Table[Opacity[1], {5}], Table[Directive[Thickness[0.01], Opacity[0.3]], {20}]]}, Themes`$ColorWeight]; $\endgroup$
    – Mr.Wizard
    Commented May 11, 2017 at 23:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.