Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non overlapping error bars in line plot

Tags:

I am using Pandas and Matplotlib to create some plots. I want line plots with error bars on them. The code I am using currently looks like this

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

df = pd.DataFrame(index=[10,100,1000,10000], columns=['A', 'B', 'C', 'D', 'E', 'F'], data=np.random.rand(4,6))
df_yerr = pd.DataFrame(index=[10,100,1000,10000], columns=['A', 'B', 'C', 'D', 'E', 'F'], data=np.random.rand(4,6))

fig, ax = plt.subplots()
df.plot(yerr=df_yerr, ax=ax, fmt="o-", capsize=5)
ax.set_xscale("log")
plt.show()

With this code, I get 6 lines on a single plot (which is what I want). However, the error bars completely overlap, making the plot difficult to read.

Is there a way I could slightly shift the position of each point on the x-axis so that the error bars no longer overlap?

Here is a screenshot:

enter image description here

like image 482
JNevens Avatar asked Dec 14 '17 09:12

JNevens


People also ask

What does it mean if the error bars do not overlap?

When standard deviation error bars do not overlap, it's a clue that the difference may be significant, but you cannot be sure. You must actually perform a statistical test to draw a conclusion. The standard deviation is NOT a statistical test, rather the standard deviation is a measure of variability.

Are error bars supposed to overlap?

When the difference between two means is statistically significant (P < 0.05), the two SD error bars may or may not overlap. Likewise, when the difference between two means is not statistically significant (P > 0.05), the two SD error bars may or may not overlap.

Can you have error bars on line graphs?

Error Bars can be applied to graphs such as Scatterplots, Dot Plots, Bar Charts or Line Graphs, to provide an additional layer of detail on the presented data. Error Bars help to indicate estimated error or uncertainty to give a general sense of how precise a measurement is.


1 Answers

One way to achieve what you want is to plot the error bars 'by hand', but it is neither straight forward nor much better looking than your original. Basically, what you do is make pandas produce the line plot and then iterate through the data frame columns and do a pyplot errorbar plot for each of them such, that the index is slightly shifted sideways (in your case, with the logarithmic scale on the x axis, this would be a shift by a factor). In the error bar plots, the marker size is set to zero:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

colors = ['red','blue','green','yellow','purple','black']

df = pd.DataFrame(index=[10,100,1000,10000], columns=['A', 'B', 'C', 'D', 'E', 'F'], data=np.random.rand(4,6))
df_yerr = pd.DataFrame(index=[10,100,1000,10000], columns=['A', 'B', 'C', 'D', 'E', 'F'], data=np.random.rand(4,6))

fig, ax = plt.subplots()
df.plot(ax=ax, marker="o",color=colors)

index = df.index
rows = len(index)
columns = len(df.columns)

factor = 0.95
for column,color in zip(range(columns),colors):
    y = df.values[:,column]
    yerr = df_yerr.values[:,column]
    ax.errorbar(
        df.index*factor, y, yerr=yerr, markersize=0, capsize=5,color=color,
        zorder = 10,
    )
    factor *= 1.02

ax.set_xscale("log")
plt.show()

As I said, the result is not pretty:

result of the code above

UPDATE

In my opinion a bar plot would be much more informative:

fig2,ax2 = plt.subplots()
df.plot(kind='bar',yerr=df_yerr, ax=ax2)
plt.show()

result of second piece of code

like image 173
Thomas Kühn Avatar answered Oct 04 '22 12:10

Thomas Kühn