# Consecutive PlotStyle across multiple plots

## Problem

I would like to use consecutive PlotStyles (e.g. from ColorData[...]) across different Plot/ListPlot/ListLinePlot commands. That is: each plot should pick colors from the list starting where the previous plot stopped.

In other words: I want

Show[
Plot[{f[x], g[x]}, ... , PlotStyle -> cs],
Plot[{h[x], i[x]}, ... , PlotStyle -> cs]
]


to be equivalent to

Plot[{f[x], g[x], h[x], i[x]}, ... , PlotStyle -> cs]


But I still want to have the same automatic color schemes for e.g. Show[Plot[...], ListPlot[...]].

## First attempt

Since the PlotStyle -> ColorData[n] options seems to call ColorData[n][k] with increasing index k, I created a wrapper to make sure that k always increases:

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


Now

c = ic[];
Table[c[n], {n, 1, 5}]
Table[c[n], {n, 1, 5}]


returns

{1, 2, 3, 4, 5}
{6, 7, 8, 9, 10}


And I can do the same with indexed ColorDataFunctions like so color = ic[ColorData[n][#] &]. Repeated calls of color[1] will return consecutive colors.

But repeated Plot[..., PlotStyle -> color] will always restart from the beginning.

• works as expected if you use PlotStyle->color[1]
– kglr
Jun 7, 2019 at 9:46
• @kglr Not for me. See the edit. PlotStyle -> color[1] will only give different colors for different Plot[...] calls, not for different functions within a single Plot[...]. Jun 7, 2019 at 10:05
• With multiple functions (say 2) using PlotStyle->Table[color[1],{2}] works for both within and across plots.
– kglr
Jun 7, 2019 at 10:16
• @kglr Yes, it does. But it needs redundant a-priori knowledge about the number of functions in the PlotStyle option, which is one of the things I am trying to avoid. Jun 7, 2019 at 10:25
• DLichti, i posted an alternative approach that doesn't require knowledge of how many functions/lists appear in the first argument of plot/listplot...
– kglr
Jun 7, 2019 at 10:47

You can use color to define a function style and wrap the first argument of plot/chart functions with style to get the colors updated both within and across plots:

ClearAll[color, style]
color = ic[(ColorData[3][#] &)];
style = Style[#, color[1]]& /@ #&;

Show[Plot[Evaluate@style@{Sin[x], Cos[x]}, {x, 0, 2Pi}, PlotLegends -> "Expressions"],
Plot[Evaluate @ style @ {x Sin[x], x Cos[x]}, {x, 0, 2Pi}, PlotLegends -> "Expressions"],
PlotRange -> All]


color = ic[(ColorData[3][#] &)];
Plot[Evaluate @ style @ {Sin[x], Cos[x], x Sin[x], x Cos[x]}, {x,0, 2Pi},
PlotLegends -> "Expressions"]


Another example:

color = ic[(ColorData[43][#] &)];
style = Style[#,color[1]]&/@#&;


The first execution of

Row[{Plot[Evaluate @ style @ {Sin[x], Cos[x]}, {x, 0, 2 Pi},
BaseStyle -> Thick, ImageSize->200]
ListLinePlot[style @ RandomReal[1, {2, 10, 2}],
BaseStyle -> PointSize[Large], ImageSize->200]
PieChart[style @ Range[3], ImageSize->200]}]


gives

the second and third executions give

• Hm, I really hoped, this would be possible without messing with the first argument. Now, the style function will evaluate the first argument before Plot can extract the informations for PlotLegends -> "Expressions". Is there a way to keep the argument of style unevaluated? Jun 7, 2019 at 12:51
• @DLichti, afaik we do need Evaluate when the function arguments are wrapped. In older versions (e.g. version 9) you could use a function for PlotStyle. So Plot[{Sin[x], Cos[x]}, {x, 0, Pi}, PlotStyle -> ({clock[1],#}&/@#&)] would give the desired result. But in versions 11+ this trick no longer works.
– kglr
Jun 7, 2019 at 13:09