Shade a ListLinePlot of many series with their deviations

Consider a single list of data avg = {.5, .6, .5,...} with corresponding standard deviations dev = {.1, .2, .2, ...}.

I use some pretty verbose code...

ListLinePlot[
{avg, avg + dev, avg - dev},
PlotStyle -> {Blue, None, None},
Filling -> {1 -> {2}, 1 -> {3}}
]

to create a plot like this which shows the data (the blue line) and shades the region spanned by 2x standard deviations of each datum (like a continuous error bar).

There are clearly problems with this method, chiefly that I had to manually specify the colour palette (Blue in PlotStyle).

This becomes a pain when I want to present multiple series. Imagine I had list-of-lists avgs = {{.5, ...}, {.6, ...}} and similarly structured standard deviations devs. To plot the first 3 of my series, I can do

ListLinePlot[
{
avgs[], avgs[] + devs[], avgs[] - devs[],
avgs[], avgs[] + devs[], avgs[] - devs[],
avgs[], avgs[] + devs[], avgs[] - devs[]
},
PlotStyle -> {
Blue, None, None,
Orange, None, None,
Red, None, None
},
Filling -> {
1 -> {2}, 1 -> {3},
4 -> {5}, 4 -> {6},
7 -> {8}, 7 -> {9}
}
]

to produce I now need to plot about 30 series like this!

While it's easy (albeit seemingly unnecessary) to create the first and third arguments to ListLinePlot programmatically, constructing PlotStyle in this way is painful for a general number of series.

So; is there a less-crude way to go about this? Could I otherwise get some help in automating PlotStyle to use/wrap-around a colour palette?

Update: Wrapping all in a function:

ClearAll[deviationslLLP]
deviationslLLP[ave_, dev_, opts: OptionsPattern[]] := Module[{fill =
Join @@ (Thread[Range[Length@ave] ->
List/@(Length[ave] # + Range[Length@ave])]& /@ {1, 2}),
apd = Style[#, Opacity] & /@ (ave + dev),
amd = Style[#, Opacity] & /@ (ave - dev)},
ListLinePlot[Join @@ {ave, apd, amd}, Filling -> fill, opts]]

Examples:

dt = RandomVariate[NormalDistribution[1, .05], {10, 50}];
averages = Mean[# dt] & /@ Range;
sdevs = StandardDeviation[# dt] & /@ Range;

deviationslLLP[averages, sdevs, Frame -> True, ImageSize -> 500,
PlotLegends -> RandomWord["Noun", 10]]] You can wrap ave - dev and ave + dev pieces of your data with Style[#, Opacity]& to avoid using PlotStyle:

dt = RandomVariate[NormalDistribution[1, .1], {10, 50}];
averages = Mean[# dt] & /@ {1, 2, 3};
sdevs = StandardDeviation[# dt] & /@ {1, 2, 3};
aplussd = Style[#, Opacity]&/@(averages + sdevs);
aminussd = Style[#, Opacity]&/@(averages - sdevs);
fillings[n_] := Join @@ (Thread[Range[n] -> List/@(n # + Range[n])]& /@ {1, 2});

ListLinePlot[Join@@{averages, aplussd, aminussd}, Filling -> fillings[Length @ averages]] If you wish yo use PlotStyle you can to specify three colors, say, PlotStyle->{Red, Green,Purple}] to get Or PlotStyle->{Automatic, Green,Purple}] to get Use NormalDistribution[1, .05] instead of NormalDistribution[1, .1] and Range instead of {1,2,3} to get Add the option PlotStyle -> 63 to get • This is exactly what I'm looking for (though I've had a hard time controlling evaluation order when wrapping this in a function) – Anti Earth Jan 19 '18 at 16:55
• @AntiEarth, please see the update. – kglr Jan 19 '18 at 18:01

Maybe use a function like makePlot in MapThread:

makePlot = Function[{avg, dev, col},
ListLinePlot[{avg, avg - dev, avg + dev},
PlotStyle -> {col, None, None}, Filling -> {1 -> {2}, 1 -> {3}}]];

plots = MapThread[makePlot, {avgs, devs, {Blue, Orange, Red}}];

Show[plots]
• Automating the args is the easy part; I'm looking for help in not having to explicitly specify a fixed-length colour palette (also using Show introduces new problems; I'd prefer to avoid it) – Anti Earth Jan 19 '18 at 15:41

I have the sense that this has been answered before, but a quick look couldn't find it, so here's my quick take on it:

ClearAll[varianceListPlot];
Options[varianceListPlot] =
Options[ListLinePlot];
varianceListPlot[
domMainLowHigh :
{
Repeated[
{
{__?NumericQ},
{__?NumericQ},
{__?NumericQ},
{__?NumericQ}
}
]
},
ops : OptionsPattern[]
] /; Length[DeleteDuplicates[Map[Length, domMainLowHigh, {2}]]] ==
1 :=
With[
{
plots =
Join @@
Map[
With[{dom = #[]},
Map[
{#[], #[] + #[], #[] - #[]}
]
] &,
domMainLowHigh
],
ps = Replace[OptionValue[PlotStyle], Automatic :> ColorData]
},
ListLinePlot[
plots,
PlotStyle ->
Table[
If[Mod[i, 3] == 1,
If[ListQ@ps,
ps[[Mod[Floor[i/3] + 1, Length@ps, 1]]],
Replace[ps[Floor[i/3] + 1], _ps :> ps]
],
None
],
{i, Length@plots}
],
ops,
Filling ->
Flatten@
Table[
{
i -> {i + 1},
i -> {i + 2}
},
{i, 1, Length@plots, 3}
]
]
];
varianceListPlot[
Repeated[{{_?NumericQ, _?
NumericQ, {Repeated[_?NumericQ, 2]}}, ___}],
ops : OptionsPattern[]
] :=
varianceListPlot[
{#[[All, 1]], #[[All, 2]], #[[All, 3, 1]], #[[All, 3, 2]]} & /@
ops
];
varianceListPlot[
dd :
{
{__?NumericQ},
{__?NumericQ},
{__?NumericQ},
{__?NumericQ}
},
ops : OptionsPattern[]
] :=
varianceListPlot[{dd}, ops];
varianceListPlot[
dataDevs : {{_?NumericQ, _?
NumericQ, {Repeated[_?NumericQ, 2]}}, ___},
ops : OptionsPattern[]
] :=

I provided a two syntaxes; either you pass the domain, main plot, upper variance, and lower variance as a 4-tuple for each data set or you can do it point-wise as {x, y, {above, below}} and it'll unwrap to the prior syntax.

varianceListPlot[
{
{
dom,
Sin[dom],
ConstantArray[1, Length@dom],
ConstantArray[1, Length@dom]
},
{
dom,
Cos[dom],
ConstantArray[1, Length@dom],
ConstantArray[1, Length@dom]
},
{
dom,
3*Cos[dom/π],
ConstantArray[1, Length@dom],
ConstantArray[1, Length@dom]
}
}
] 