我正在尝试获取带有误差线的3D条形图。 我愿意使用matplotlib,seaborn或任何其他python库或工具
在SO中进行搜索,我发现可以通过绘制多个2D图(here for example)来完成3D条形图。这是我的代码:
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()
我得到了3D“ ish”图。
我的问题是:如何添加错误栏?
为简便起见,让我们尝试向所有绘图添加相同的误差线:
yerr=[10,10,10,10,10,10,10,10,10,10]
如果我在每个“ 2D”图中添加我的误差线:
ax.bar(xs, ys, zs, zdir='y', color=cs,yerr=[10,10,10,10,10,10,10,10,10,10], alpha=0.8)
不起作用:
AttributeError: 'LineCollection' object has no attribute 'do_3d_projection'
我也尝试添加:
#ax.errorbar(xs, ys, zs, yerr=[10,10,10,10,10,10,10,10,10,10], ls = 'none')
但是还是一个错误:
TypeError: errorbar() got multiple values for keyword argument 'yerr'
有人知道我如何获得带有误差线的3D曲线图吗?
答案 0 :(得分:3)
据我所知,没有直接的方法可以在3d中做到这一点。但是,您可以创建如下所示的解决方法。该解决方案的灵感来自here。这里的技巧是传递两个垂直放置的点,然后使用_
作为标记来充当误差线的上限。
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')
答案 1 :(得分:2)
首先,当2D绘图就足够时就不要使用3D绘图,在这种情况下就可以。对2D数据使用3D图会不必要地混淆事物。
第二,您可以结合使用MultiIndex pandas数据框来获得所需的结果:
df = pd.DataFrame({
'a': list(range(5))*3,
'b': [1, 2, 3]*5,
'c': np.random.randint(low=0, high=10, size=15)
}).set_index(['a', 'b'])
fig, ax = plt.subplots(figsize=(10,6))
y_errs = np.random.random(size=(3, 5))
df.unstack().plot.bar(ax=ax, yerr=y_errs)
这将产生如下图:
我在这里使用'bmh'
样式(即我在打开的笔记本中早些时候打过plt.style.use('bmh')
),这就是它看上去的样子。