【问题标题】:Python matplotlib 3D bar plot with error bars带有误差线的 Python matplotlib 3D 条形图
【发布时间】:2019-01-18 16:56:28
【问题描述】:

我正在尝试获得带有误差线的 3D 条形图。 我愿意使用 matplotlib、seaborn 或任何其他 python 库或工具

在 SO 中搜索我发现可以通过绘制几个 2D 图来完成 3D 条形图 (here for example)。这是我的代码:

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 绘图条吗?

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    据我所知,没有直接的方法可以在 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')
    

    【讨论】:

    • 很好的解决方案!正是我所要求的。
    【解决方案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')),这就是它看起来如此的原因。

    【讨论】:

    • 也感谢您的回答。这也很有帮助。你说得对,我不需要为这些数据绘制 3d 图,但我只是简化了数据以使代码更容易。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 2015-04-08
    • 1970-01-01
    相关资源
    最近更新 更多