3

For Seaborn lineplot, it seems pretty easy to plot the Standard Deviation by specifying ci='sd'. Is there a way to plot 2 times the standard deviation?

For example, I have a graph like this:

enter image description here

sns.lineplot(data=df, ax=x, x='day_of_week', y='y_variable', color='lightgrey', ci='sd')

Is there a way to make it so the "CI" plotted is 2 times the standard deviation?

Vincent
  • 7,808
  • 13
  • 49
  • 63
  • 2
    Please provide an MCVE to initialize the dataframe. If seaborn is just doing `df.groupby('day_of_week')`, then you can replicate the calculation – Mad Physicist May 17 '21 at 19:55
  • Not in any current released version, but in the development version, [yes](https://github.com/mwaskom/seaborn/pull/2407). – mwaskom May 17 '21 at 19:59
  • Does this answer your question? [How to use custom error bar in seaborn lineplot](https://stackoverflow.com/questions/56203420/how-to-use-custom-error-bar-in-seaborn-lineplot) – Trenton McKinney May 18 '21 at 22:15

2 Answers2

1

Recent versions of seaborn (>v0.12) changed how to specify the error bar, and now allow passing a scale parameter together with the choice of error measurement (e.g., standard deviation).

Check this link Statistical estimation and error bars for more info.

So, to plot 2x Standard Deviation in Seaborn you just need to pass this parameter: errorbar=('sd', 2)

Mauricio Perez
  • 190
  • 1
  • 7
0

I didn't find a solution within the seaborn, but a walk-around way is by using matplotlib.pyplot.fill_between, as, e.g., was done in this answer, but also in the thread suggested in the comments.

Here is my implementation:

import matplotlib.pyplot as plt
import seaborn as sns

sns.set_theme()

flights = sns.load_dataset("flights")
fig, axs = plt.subplots(1, 2, figsize=(12, 6), sharey=True)
sns.lineplot(data=flights, x="year", y = "passengers", ci="sd", ax=axs[0])
axs[0].set_title("seaborn")

nstd = 1.
means = flights.groupby("year")["passengers"].mean()
stds = flights.groupby("year")["passengers"].std()
axs[1].plot(means.index, means.values)
for nstd in range(1, 4):
    axs[1].fill_between(means.index, (means - nstd*stds).values, (means + nstd*stds).values, alpha=0.3, label="nstd={}".format(nstd))
axs[1].legend(loc="upper left")
axs[0].set_title("homemade")
plt.savefig("./tmp/flights.png")
plt.close(fig)

The resulting figure is enter image description here

Roger Vadim
  • 373
  • 2
  • 12