【问题标题】:How can I plot bar plots with variable widths but without gaps in Python, and add bar width as labels on the x-axis?如何在 Python 中绘制宽度可变但没有间隙的条形图,并将条形宽度添加为 x 轴上的标签?
【发布时间】:2022-01-25 08:30:44
【问题描述】:

我有三个列表:x、y 和 w,如图所示: x 是对象的名称。 y 是它的高度,w 是它的宽度。

x = ["A","B","C","D","E","F","G","H"]

y = [-25, -10, 5, 10, 30, 40, 50, 60]

w = [30, 20, 25, 40, 20, 40, 40, 30]

我想在 Python 的条形图中绘制这些值,这样 y 代表高度,w 代表条形的宽度。

当我使用它来绘制它时

colors = ["yellow","limegreen","green","blue","red","brown","grey","black"]

plt.bar(x, height = y, width = w, color = colors, alpha = 0.8)

我得到一个如图所示的情节:

接下来,我尝试对宽度进行规范化,以便条形不会相互重叠使用

w_new = [i/max(w) for i in w]
plt.bar(x, height = y, width = w_new, color = colors, alpha = 0.8)
#plt.axvline(x = ?)
plt.xlim((-0.5, 7.5))

我得到了比以前更好的结果,如图所示:

但是,钢筋之间的间隙仍然不均匀。例如,B 和 C 之间有很大的差距。但是F和G之间没有差距。

我想绘制两个连续条之间的间隙宽度均匀或没有间隙的图。它应该如图所示:

如何在 Python 中创建这种类型的绘图?是否可以使用任何数据可视化库,例如 matplotlib、seaborn 或 Plotly?如果数据在数据框中可用,是否有任何替代方法?

此外,我想在绘图右侧添加 A、B、C 等标签,而是将条形的实际宽度作为 x 轴上的标签(例如用红色数字表示上面的 x 轴图)。我还想在距离 x 轴 50 处添加一条垂直红线。我知道这可以使用plt.axvline(x = ...) 添加但我不确定我应该将 x 声明为什么值,因为 W 的比例与 x 轴的长度不精确。

【问题讨论】:

    标签: python python-3.x pandas matplotlib seaborn


    【解决方案1】:

    IIUC,你可以试试这样的:

    import matplotlib.pyplot as plt
    
    x = ["A","B","C","D","E","F","G","H"]
    
    y = [-25, -10, 5, 10, 30, 40, 50, 60]
    
    w = [30, 20, 25, 40, 20, 40, 40, 30]
    
    colors = ["yellow","limegreen","green","blue","red","brown","grey","black"]
    
    #plt.bar(x, height = y, width = w, color = colors, alpha = 0.8)
    
    xticks=[]
    for n, c in enumerate(w):
        xticks.append(sum(w[:n]) + w[n]/2)
        
    w_new = [i/max(w) for i in w]
    a = plt.bar(xticks, height = y, width = w, color = colors, alpha = 0.8)
    _ = plt.xticks(xticks, x)
    
    plt.legend(a.patches, x)
    

    输出:

    或更改条形宽度的 xticklabels:

    xticks=[]
    for n, c in enumerate(w):
        xticks.append(sum(w[:n]) + w[n]/2)
        
    w_new = [i/max(w) for i in w]
    a = plt.bar(xticks, height = y, width = w, color = colors, alpha = 0.8)
    _ = plt.xticks(xticks, w)
    plt.legend(a.patches, x)
    

    输出:

    【讨论】:

    • 谢谢。您能否建议如何在图例中添加标签 A、B、C 等?
    • 嗨,斯科特,这是一个非常有用的答案,谢谢。我还有一个问题要问你——我正在制作一个类似的图表,但是每个 x 变量都有多个实例(例如,可能有 3 个“G”值)。我将如何创建此图表,以便图例仅引用每个变量一次(并根据每个变量应用相同的颜色)?
    • @Jwem93 嗨,谢谢。在没有看到您的数据或您的数据和代码的小样本的情况下,我很难给您一个好的答案。您可以创建一个新问题并在此组中发布您的示例吗?
    • 嗨@Scott,没问题我会这样做。谢谢
    • 您好,这是我的帖子:stackoverflow.com/questions/70631459/…
    【解决方案2】:

    我想出了另一种方法来做到这一点。

    x = ["A","B","C","D","E","F","G","H"]
    
    y = [-25, -10, 5, 10, 30, 40, 50, 60]
    
    w = [30, 20, 25, 40, 20, 40, 40, 30]
    
    xpos = []
    
    a = 0
    for i in range(len(w)):
        if i == 0:
            a+=w[i]
           
            xpos.append(w[i]/2)
            
        else:
            a += w[i]
           
            xpos.append(a - w[i]/2)
    
    colors = ["yellow","limegreen","green","blue","red","brown","grey","black"]
    
    
    fig = plt.bar(xpos,
            height = y,
            width = w,
            color = colors,
            alpha = 0.5,
          )
    
    plt.xticks(ticks = xpos, labels = w)
    
    plt.xlim((0, 245))
    plt.axvline(x = 150)
    plt.legend(fig.patches, x)
    
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-30
      • 2020-04-23
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      • 2019-10-31
      • 1970-01-01
      相关资源
      最近更新 更多