6
$\begingroup$

For functions that can produce multiple "style-able" entities, Mathematica by default will give each such entity a different style. Similar conventions apply to other features, either by default, or when Automatic is specified as their setting. For example, in ListPlot, if multiple curves are being displayed, then specifyingPlotMarker->Automatic results in a different choice of plot marker for each curve.

Very often I want to disable this behavior. E.g., I want all the curves produced by a single call to a plotting function to be shown with the same style, same plot marker, etc.

How can I do this?

NOTE that what I want to do is not the same thing as setting an explicit style, plot marker, etc., to be applied to all the entities. I specifically want to avoid having to choose some style, plot marker, etc! I just want Mathematica to use the same default style, plot marker, etc. (whatever those are) for all entities.

$\endgroup$

3 Answers 3

6
$\begingroup$

Sequence trick

Update: in recent versions Sequence is specifically handled meaning it cannot be used for this "trick" -- however the mechanism is still valid and alternatives can be used.

As detailed in Plot draws list of curves in same color when not using Evaluate if items are initially contained in a Head besides List they are seen as one expression by the style mechanism; if that head later vanishes, allowing it to plot normally, the style remains.

Plot[{1, ## &[2, 3], 4}, {x, 0, 1},
  PlotRange -> {0, 5},
  PlotStyle -> Thick
]

enter image description here

I illustrated grouping two lines into the same style to show the flexibility of this method but you could just as easily group all the lines as one:

Plot[{## &[1, 2, 3, 4]}, {x, 0, 1},
  PlotRange -> {0, 5},
  PlotStyle -> Thick
]

enter image description here

I don't know how many other plot types this applies to but it does include ParametricPlot:

ParametricPlot[
 {{2 Cos[t], 2 Sin[t]}, 
  ## &[{2 Cos[t], Sin[t]}, {Cos[t], 2 Sin[t]}],
  {Cos[t], Sin[t]}},
 {t, 0, 2 Pi},
 PlotStyle -> Thick
]

enter image description here


Option selector

I suspect your aversion to specifying a PlotStyle has to do with remembering the default values for the different plot types. If this is the case I suggest that you use a method to fill in these values automatically. For each individual plot type you could define behavior for using PlotStyle -> "Uniform" as I did for FillingStyle -> "Match" (S.O.8569242). Or you could use a framework such as the one Leonid laid out in (22697), but I believe you will still have to deal with multiple configurations because e.g. setting PlotMarkers for ListPlot will cause all plots to have plot markers (by default) when they did not before.

An alternative to an option selector would be to craft a function that works with the output of each type of plot function to remove styling after-the-fact. This is probably a less ideal way to go but it may still have application.

Here is a working implementation of the first proposed method (from my Stack Overflow post):

Unprotect[Plot, ListPlot, ListLinePlot];

(#[a__, b : OptionsPattern[]] := 
     Block[{$psUni = True}, 
        With[{val = ColorData[1, 1]}, #[a, PlotStyle -> val, b]]] /; ! TrueQ[$psUni] /; 
      OptionValue[PlotStyle] === "Uniform") & /@ {Plot, ListPlot, ListLinePlot};
(#[a__, b : OptionsPattern[]] := 
     Block[{$pmUni = True}, 
        With[{val = System`Private`$PlotMarkers[[1]]}, #[a, PlotMarkers -> val, b]]] /; ! 
        TrueQ[$pmUni] /; OptionValue[PlotMarkers] === "Uniform") & /@ {ListPlot, 
   ListLinePlot};

Now:

data = Table[{k, PDF[BinomialDistribution[50, p], k]}, {p, {0.3, 0.5, 0.8}}, {k, 0, 50}];
ListLinePlot[data, PlotStyle -> "Uniform", PlotMarkers -> "Uniform"]

enter image description here

$\endgroup$
7
  • 1
    $\begingroup$ That's really nice trick! +1 ;) $\endgroup$
    – Kuba
    Sep 8, 2013 at 15:19
  • $\begingroup$ @Kuba Thank you. :-) $\endgroup$
    – Mr.Wizard
    Sep 8, 2013 at 15:51
  • $\begingroup$ It is one of those "so obvious when you know them" tricks :) $\endgroup$
    – Kuba
    Sep 8, 2013 at 15:59
  • 1
    $\begingroup$ @Kuba I don't think it's obvious at all. I had to ask my own question about it. $\endgroup$
    – Mr.Wizard
    Sep 8, 2013 at 16:05
  • 1
    $\begingroup$ @mrc In 10.0.2 you can use {1, ## &[2, 3], 4} however it was reported to me that this does not work in 10.1.0, but I am not using that version yet so I cannot look for alternatives. $\endgroup$
    – Mr.Wizard
    Apr 20, 2015 at 1:17
4
$\begingroup$

Your question is rather broad. I don't know an answer that I'm confident will work for any '"style-able" entities', but mapping a plot expression over the entities you want to plot and using Show will work for some cases.

data = Table[Sin[k x], {k, 3}, {x, 0, 2 Pi, 0.1}];
ListPlot[data, Joined -> True, PlotMarkers -> {Automatic, 7}]

plot.1.png

Show[
  ListPlot[#, Joined -> True, PlotMarkers -> {Automatic, 7}] & /@ data]

plot.2.png

Edit

In my example above, each of the three plots naturally have the same plot range, but as Mr.Wizard points out, this is not always the case. Since Show, given no other instructions, will use the plot range of the first curve, something might have to be done to override the domination of the first curve.

data2 = Table[k Sin[k x], {k, 3}, {x, 0, 2 Pi, 0.1}];
Show[ListPlot[#, Joined -> True, PlotMarkers -> {Automatic, 7}] & /@ data2]

plot.3.png

Show[
  ListPlot[#, Joined -> True, PlotMarkers -> {Automatic, 7}] & /@ data2, 
    PlotRange -> All]

plot.4.png

$\endgroup$
1
  • $\begingroup$ Oops. Thanks for catching my mistake. Seeing nested Table for the third time was making me crazy. :-p $\endgroup$
    – Mr.Wizard
    Sep 8, 2013 at 16:24
1
$\begingroup$

In Plot-like functions you can always style all the curves and points identically by specifying the PlotStyle option in a non-List form (for example, PlotStyle -> Blue or PlotStyle -> Directive[Blue, PointSize[Medium]]) or equivalently as a List with only one element: PlotStyle -> {style}:

data = Table[{x, Sin[k x]}, {k, 3}, {x, 0, 2 Pi, 0.1}];

ListLinePlot[data, Mesh -> All, 
 PlotStyle -> Directive[Blue, PointSize[Medium]]]

The following is a low-level solution which does not rely on high-level functions and guarantees exact positioning of the graphics primitives:

Graphics[{Blue, Line@#1, PointSize[Medium], Point@#1} & /@ data, 
 Axes -> True, AspectRatio -> 1/GoldenRatio]

plot

$\endgroup$

Your Answer

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

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