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

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


Legacy Solution

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.


Here is one take on it -- the hard part was estimating how the PlotStyle option is turned into a list of directives. I think this works as the internal implementation:

canonicalPlotStyle::usage = 
  "Turn a PlotStyle option into the canonical form {_Directive...}";
canonicalPlotStyle[ps_] := Replace[ps, {
   a_List :> (Flatten[Directive @@ Flatten[{#}]] &) /@ a,
   a_ :> {Flatten@Directive[a]}}]

Building on canonicalPlotStyle it's now just a matter of combining two lists of unequal length:

also::usage = 
  "Combines a specified plotstyle with the current defaults as \
  specified by Options.";
also[plotstyle_] := Module[{ps, n},
  ps = canonicalPlotStyle /@ {
     (PlotStyle /. Options[Plot]) /. Automatic :> ColorData[1, "ColorList"],
     plotstyle};
  n = LCM @@ (Length /@ ps);
  Join @@@ Transpose[Flatten[Table[#, {n/Length[#]}], 1] & /@ ps ]]

This does require you to call the function when you plot, but I couldn't see any way around that part:

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

output from above code

HTH


This is work in progress, I'm posting it because I'm not sure to be able to finish it, and perhaps someone wants to.

The idea is to combine the wonderful Janus's solution with this nice trick to redefine the Plot[ ] standard behavior.

The program below works for a large subset of the help page for Plot[ ], but fails for two or three. The code is not tidied up, just a draft with leftovers.

Unprotect[Plot];
Plot[argsANDopts___] :=
  Block[
    {$inMsg = True, result, also, canonicalPlotStyle, opts, args, 
     optPstyle},

    If[(opts = 
        FilterRules[Cases[{argsANDopts}, _Rule], Options[Plot]]) == {},
     opts = {Axes -> (Axes /. Options[Plot])}];(*Anything not null*)
    args = Cases[{argsANDopts}, Except@_Rule];

    If[(optPstyle = Cases[opts, Rule[PlotStyle, y__] :> y]) == {}, 
     optPstyle = (PlotStyle /. Options[Plot])];

    canonicalPlotStyle[ps_] := 
     Replace[ps, {a_List :> (Flatten[Directive @@ Flatten[{#}]] &) /@ 
         a, a_ :> {Flatten@Directive[a]}}];

    also[plotstyle_] := 
     Module[{ps, n}, 
      ps = canonicalPlotStyle /@ {(PlotStyle /. Options[Plot]) /. 
          Automatic :> ColorData[1, "ColorList"], plotstyle};
      n = LCM @@ (Length /@ ps);
      Join @@@ Transpose[Flatten[Table[#, {n/Length[#]}], 1] & /@ ps]];

    (*Print@opts;
    Print@args;
    Print@optPstyle;
    Print@Evaluate@also[opts];*)
    result = Plot[
      Evaluate@Sequence@@args,
      PlotStyle -> also[optPstyle],
      Evaluate@Sequene@@opts
      ];
    result

    ] /; ! TrueQ[$inMsg];
SetOptions[Plot, PlotStyle -> ColorData[3, "ColorList"]];
Protect[Plot];

samples:

enter image description here

Does not work for:

Plot[{Sin[x], Sin[2 x], Sin[3 x]}, {x, 0, 2 Pi}, 
 PlotStyle -> {Red, Green, Blue}]