如何绘制宽度可变但 Python 中没有间隙的条形图,并在 x 轴上添加条形宽度作为标签?
How can I plot bar plots with variable widths but without gaps in Python, and add bar width as labels on the x-axis?
我有三个列表: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?如果数据在 dataframe 中可用,是否有其他替代方法?
此外,我想在图的右侧添加 A、B、C 等标签,而是将条形的实际宽度作为 x 轴上的标签(例如,用红色表示上面 x 轴图中的数字)。我还想在距离 x 轴 50 处添加一条垂直红线。我知道这可以使用 plt.axvline(x = ...)
添加,但我不确定我应该将 x 的值表示为多少,因为 W 的比例与 x 轴的长度不完全一致。
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)
输出:
我想出了一个替代方法。
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()
我有三个列表: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?如果数据在 dataframe 中可用,是否有其他替代方法?
此外,我想在图的右侧添加 A、B、C 等标签,而是将条形的实际宽度作为 x 轴上的标签(例如,用红色表示上面 x 轴图中的数字)。我还想在距离 x 轴 50 处添加一条垂直红线。我知道这可以使用 plt.axvline(x = ...)
添加,但我不确定我应该将 x 的值表示为多少,因为 W 的比例与 x 轴的长度不完全一致。
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)
输出:
我想出了一个替代方法。
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()