如何在 Python 中绘制宽度可变但没有间隙的条形图,并将条形宽度添加为 x 轴上的标签?

hbs*_*123 2 python matplotlib python-3.x pandas seaborn

我有三个列表: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]
Run Code Online (Sandbox Code Playgroud)

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

当我使用它绘制它时

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

plt.bar(x, height = y, width = w, color = colors, alpha = 0.8)
Run Code Online (Sandbox Code Playgroud)

我得到一个如图所示的图: 在此输入图像描述

接下来,我尝试使用以下方法标准化宽度,以便条形图不会彼此重叠

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))
Run Code Online (Sandbox Code Playgroud)

我得到了比以前更好的结果,如下所示: 在此输入图像描述

然而,条形之间的间隙仍然不均匀。例如,B和C之间存在很大差距。但F和G之间,没有差距。

我希望绘制出两个连续条之间有均匀间隙宽度或没有间隙的图。它应该看起来如图所示:在此输入图像描述

如何在 Python 中创建这种类型的图?是否可以使用任何数据可视化库,例如 matplotlib、seaborn 或 Plotly?如果数据框中的数据可用,是否有其他选择可以做到这一点?

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

Sco*_*ton 6

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)
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述

或者更改 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)
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述