Skip to main content

plotting - How to change the default ColorData used in Mathematica's Plot?



This question leads on from the recent question What are the standard colors for plots in Mathematica?


There it was determined that the default color palette used by Plot is equivalent to ColorData[1] (see the note at the end). This can be changed through the use of the option PlotStyle.


My question is how can we make, e.g., the default color palette be ColorData[3] and have this default survive manual changes to other aspects of the plot styling?




So, for example, let's make a list of monomials and some dashing settings


fns = Table[x^n, {n, 0, 5}];
dash = Table[AbsoluteDashing[i], {i, 1, 6}];

Note that the default plot colors survive other choices to styling:


GraphicsRow[{Plot[fns, {x, -1, 1}], Plot[fns, {x, -1, 1}, PlotStyle -> dash]}]


default


The colors in the plot may be changed by locally setting PlotStyle, such as


Plot[fns, {x, -1, 1}, PlotStyle -> ColorData[3, "ColorList"]]

or by setting the default options. Let's do that and run the GraphicsRow command again:


SetOptions[Plot, PlotStyle -> ColorData[3, "ColorList"]];
GraphicsRow[{Plot[fns, {x, -1, 1}], Plot[fns, {x, -1, 1}, PlotStyle -> dash]}]

ColorList 3



Note that the new colors in the default plot style is overwritten by the use of PlotStyle -> dash. This can be manually fixed, in this case, with Transpose[{dash, ColorData[3, "ColorList"][[1 ;; 6]]}], but you don't want to do that every time.


Changing the default PlotStyle will always have this problem. You'd expect there to be a default ColorData or color scheme setting somewhere, but I have been unable to find it.




Note that running the hack


Unprotect[ColorData];
ColorData[1] := ColorData[3]
ColorData[1, a__] := ColorData[3, a]
Protect[ColorData];

does not fix the default plot colors. Which probably means that the default internals of Plot does not make an explicit call to ColorData...





It's also interesting to note that when running a Trace[Plot[...],TraceInternal -> True] the colors seem to appear out of nowhere! I looked at such a trace in trying to answer this recent SO question related to how Mathematica determines the number of lines and thus colors it needs in a plot.



Answer



Update August 2014


The Legacy Solution below has been corrected to work in recent versions (9 and 10).


At the same time however the introduction of PlotTheme functionality makes my solution largely academic as plot themes are designed to combine in the same manner. If no existing theme has the desired style you can create a custom one.


This example demonstrates setting new default plot colors as well a custom thickness and these correctly combining with the dashing directives in PlotStyle:


System`PlotThemeDump`resolvePlotTheme["Thick5", "Plot"] := 
Themes`SetWeight[{"DefaultThickness" -> {AbsoluteThickness[5]}},
System`PlotThemeDump`$ComponentWeight]


SetOptions[Plot, PlotTheme -> {"DarkColor", "Thick5"}];

fns = Table[x^n, {n, 0, 5}];
dash = Table[AbsoluteDashing[i], {i, 1, 6}];

Plot[fns, {x, -1, 1}, PlotStyle -> dash]

enter image description here






The following updated solution is based on the existing solutions from Janus and belisarius with considerable extension and enhancement.


Supporting functions


ClearAll[toDirective, styleJoin]

toDirective[{ps__} | ps__] :=
Flatten[Directive @@ Flatten[{#}]] & /@ {ps}

styleJoin[style_, base_] :=
Module[{ps, n},

ps = toDirective /@ {PlotStyle /. Options[base], style};
ps = ps /. Automatic :> Sequence[];
n = LCM @@ Length /@ ps;
MapThread[Join, PadRight[#, n, #] & /@ ps]
]

Main function


pp is the list of Plot functions you want to affect.


sh is needed to handle pass-through plots like LogPlot, LogLinearPlot, DateListLogPlot, etc.


pp = {Plot, ListPlot, ParametricPlot, ParametricPlot3D};


Unprotect /@ pp;

(#[a__, b : OptionsPattern[]] :=
Block[{$alsoPS = True, sh},
sh = Cases[{b}, ("MessagesHead" -> hd_) :> hd, {-2}, 1] /. {{z_} :> z, {} -> #};
With[{new = styleJoin[OptionValue[PlotStyle], sh]}, #[a, PlotStyle -> new, b]]
] /; ! TrueQ[$alsoPS];
DownValues[#] = RotateRight[DownValues@#]; (* fix for versions 9 and 10 *)
) & /@ pp;




Usage


Now different plot types may be individually styled as follows:


SetOptions[Plot, PlotStyle -> ColorData[3, "ColorList"]];

Or in groups (here using pp defined above):


SetOptions[pp, PlotStyle -> ColorData[3, "ColorList"]];




Examples


PlotStyle options are then automatically added:


fns = Table[x^n, {n, 0, 5}];
dash = Table[AbsoluteDashing[i], {i, 1, 6}];

Plot[fns, {x, -1, 1}, PlotStyle -> dash]

enter image description here




Plot[...] and Plot[..., PlotStyle -> Automatic] are consistent:



Plot[fns, {x, -1, 1}]
Plot[fns, {x, -1, 1}, PlotStyle -> Automatic]

enter image description here enter image description here




Pass-through plots (those that call Plot, ListPlot or ParametricPlot) can be given their own style:


SetOptions[LogPlot, PlotStyle -> ColorData[2, "ColorList"]];

LogPlot[{Tanh[x], Erf[x]}, {x, 1, 5}]
LogPlot[{Tanh[x], Erf[x]}, {x, 1, 5}, PlotStyle -> {{Dashed, Thick}}]


enter image description here enter image description here




PlotStyle handling can be extended to different Plot types.


I included ParametricPlot3D above as an example:


fns = {1.16^v Cos[v](1 + Cos[u]), -1.16^v Sin[v](1 + Cos[u]), -2 1.16^v (1 + Sin[u])};

ParametricPlot3D[fns, {u, 0, 2 Pi}, {v, -15, 6},
Mesh -> None, PlotStyle -> Opacity[0.6], PlotRange -> All, PlotPoints -> 25]


enter image description here




Implementation note


As it stands, resetting SetOptions[..., PlotStyle -> Automatic] will revert the colors to the original defaults. If this behavior is undesirable, the code can be modified to give a different default color, in the manner of Janus' also function, upon which my styleJoin is clearly based.


Comments

Popular posts from this blog

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Mathematica: 3D plot based on combined 2D graphs

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data. I would now like to show these different 2D plots projected in 3D as in but then using proper perspective. In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes. Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage). (* some test data *) data = Table[Null, {i, 4}]; data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 1.0}, {1, -6.8}, {2, -4.7}, {3, -1....