Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python matplotlib 3D bar plot with error bars

I am trying to get a 3D barplot with error bars. I am open to use matplotlib, seaborn or any other python library or tool

Searching in SO I found 3D bar graphs can be done by drawing several 2D plots (here for example). This is my code:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D


dades01 = [54,43,24,104,32,63,57,14,32,12]
dades02 = [35,23,14,54,24,33,43,55,23,11]
dades03 = [12,65,24,32,13,54,23,32,12,43]

df_3d = pd.DataFrame([dades01, dades02, dades03]).transpose()
colors = ['r','b','g','y','b','p']


fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
z= list(df_3d)
for n, i in enumerate(df_3d):
    print 'n',n
    xs = np.arange(len(df_3d[i]))
    ys = [i for i in df_3d[i]]
    zs = z[n]

    cs = colors[n]
    print ' xs:', xs,'ys:', ys, 'zs',zs, ' cs: ',cs
    ax.bar(xs, ys, zs, zdir='y', color=cs, alpha=0.8)


ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

I get the 3D 'ish' plot.

3D bar plot without error bars

My question is: How do I add error bars?

To make it easy, lets try to add the same error bars to all the plots:

yerr=[10,10,10,10,10,10,10,10,10,10]

If I add my error bars in each '2D' plot:

ax.bar(xs, ys, zs, zdir='y', color=cs,yerr=[10,10,10,10,10,10,10,10,10,10], alpha=0.8)

Doesn't work:

AttributeError: 'LineCollection' object has no attribute 'do_3d_projection'

I have also tried to add:

#ax.errorbar(xs, ys, zs, yerr=[10,10,10,10,10,10,10,10,10,10], ls = 'none')

But again an error:

TypeError: errorbar() got multiple values for keyword argument 'yerr'

Any idea how I could get 3D plot bars with error bars?

like image 593
daniel_hck Avatar asked Sep 13 '26 08:09

daniel_hck


1 Answers

There is no direct way to the best of my knowledge to do it in 3d. However, you can create a workaround solution as shown below. The solution is inspired from here. The trick here is to pass two points lying vertically and then use _ as the marker to act as the error bar cap.

yerr=np.array([10,10,10,10,10,10,10,10,10,10])

for n, i in enumerate(df_3d):
    xs = np.arange(len(df_3d[i]))
    ys = [i for i in df_3d[i]]
    zs = z[n]
    cs = colors[n]
    ax.bar(xs, ys, zs, zdir='y', color=cs, alpha=0.8)
    for i, j in enumerate(ys):
        ax.plot([xs[i], xs[i]], [zs, zs], [j+yerr[i], j-yerr[i]], marker="_", color=cs)

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

enter image description here

like image 141
Sheldore Avatar answered Sep 14 '26 20:09

Sheldore