# Recolour existing plots

Context

More often than not I end up doing plots one after the other so that I have a set of plots with the same colour style. When I want to make it more publishable ready, I would like to reassign colours to each line.

How to assign colours from a given style to existing sets of plots?

Example

pl1= Plot[Sin[x],{x,0,4Pi}];
pl2= Plot[Cos[2x],{x,0,4Pi}];
Show[pl1,pl2];


Attempt

I while back I wrote the following function

Clear[ShowColor];
ShowColor[list___]:=ShowColor[{list}]/; Length[{list}]>1;
ShowColor[list_,ColorRange->color__,opt___]:= Module[{len=Length[list]},
Table[list[[i]] /. RGBColor[_,_,_]->
ShowColor[list_,opt___]:= Module[{len=Length[list]},
Table[list[[i]] /. RGBColor[_,_,_]->


which uses the GradientColor Package, so that

ShowColor[{pl1,pl2}]


produces

But I am left with the impression that it could be done more elegantly and generally with the modern version of Mathematica, making use of the set of default styles and working in harmony with other features.

Also, my implementation is not very robust. For instance,

 Show[pl1, pl2] // ShowColor


fails.

What would be great would be to have a function which e.g. would take standard Options such as

 ShowColor[plots,PlotStyle-> ColorData[10]]


or

  ShowColor[plots,PlotStyle-> Directive[{Dashed,Blue}]]


Any suggestion on how to make this as generic as possible?

Thanks!

• you might find this interesting.
– kglr
Jul 1, 2019 at 17:08
• thanks for the link Jul 1, 2019 at 17:15

Using DLichti's ingenious idea / function from this q/a:

dLichtiIncrement[n0_Integer: 0, n1_Integer: 0, f_Function: Identity] :=
Module[{N0 = n0, N1 = n1}, (If[# <= N1, N0 = N0 + N1]; N1 = #; f[N0 + #]) & ]


to define a function color which increments the color every time it is invoked as color[1]:

ClearAll[color, reColor]
color = dLichtiIncrement[(ColorData[97][#] &)];
reColor[] = # /. _?ColorQ :> color[1] &;
reColor[_] := Module[{}, ClearAll[color];
color = dLichtiIncrement[(ColorData[97][#] &)]; reColor[]]


Examples:

pl1 = Plot[Sin[x], {x, 0, 4 Pi}];
pl2 = Plot[Cos[2 x], {x, 0, 4 Pi}];
Show[pl1, pl2]//reColor[]


ContourPlot[Cos[x] + Cos[y], {x, 0, 4Pi}, {y, 0, 4Pi}] // reColor[]


Plot[{x Sin[x], x Cos[x], Sin[x Cos[x]]}, {x, 0, 2 Pi},
PlotTheme -> "Monochrome", Filling -> Axis, FillingStyle -> Opacity[.5]] // reColor[]


ContourPlot[Evaluate[Sum[Sin[RandomReal[5, 2].{x, y}], {5}]], {x, 0, 5}, {y, 0, 5},
PlotTheme -> "Monochrome"] // reColor[]


 ContourPlot[Cos[x] + Cos[y], {x, 0, 4 Pi}, {y, 0, 4 Pi},


You can also use color[1] in setting ChartStyle/PlotStyle:

BarChart[{{1, 2, 3}, {1, 3, 2}}, ChartStyle -> Table[color[1], 3]]


Using reColor[blah] @ Red resets color[1] to its initial state:

 reColor[blah] @ Red == ColorData[97][1]


True

• This is almost perfect: would it be possible to give reColor an argument to allow for the colours to reincrement from the beginning? I.e. plots//reColor[] would yield the same sets of colours ? Jul 1, 2019 at 18:35
• @chris, i made small changes to allow resetting: regular call is reColor[] and reColor[anything] resets color to its initial definition.
– kglr
Jul 1, 2019 at 19:28
• Great ! I modified it slightly to choose the ColourTable: ClearAll[color, reColor] color = dLichtiIncrement[(ColorData[10][#] &)]; reColor[] = # /. _?ColorQ :> color[1] &; reColor[val_: 10] := Module[{}, ClearAll[color]; color = dLichtiIncrement[(ColorData[val][#] &)]; reColor[]] Jul 1, 2019 at 20:08
• The only remaining question is : are you nostalgic of the 70ies ? :-) Jul 2, 2019 at 8:36
• ... those were the days:)
– kglr
Jul 2, 2019 at 13:55

A simple way is to pass the coordinates in the plots to ListLinePlot.

recolor[plot_, opts___] := ListLinePlot[
Cases[plot, Line[coords_] :> coords, Infinity],
opts
]

Show[
recolor[pl1, PlotStyle -> Directive[Blue, Dashed]],
recolor[pl2, PlotStyle -> Red]
]


It can also be used to recolor already combined plots:

recolor[
Plot[{Sin[x], Cos[2 x]}, {x, 0, 4 Pi}],
PlotStyle -> {
Directive[Blue, Dashed],
Red
}]


And it also works on this:

recolor[pl3=Show[pl1, pl2],
PlotStyle -> {
Directive[Blue, Dashed],
Red
}]


You can also use existing themes:

  recolor[pl3, PlotTheme -> "Detailed"]


• @chris that's always a good idea, you never know what someone might come up with. Jul 1, 2019 at 16:56
• Thanks again for your solution: I would have accepted both if I could. Jul 2, 2019 at 13:58