You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让Pandas绘图中不同宽度的重叠条形图完美居中?

解决Pandas条形图twiny时不同宽度条形的居中重叠问题

这个问题我之前也碰到过!默认情况下用twiny()创建双x轴后,两组条形因为bar函数默认的对齐方式是左边缘(align='edge'),当宽度不同时,中心自然就错开了,确实看着很别扭。不过有两个简单的方法可以解决这个问题:

方法一:使用align='center'参数(推荐)

这是最直接的解决方案,只需要在绘制两组条形时都指定align='center',让条形的x坐标对应分类的中心位置,不管宽度怎么调整,两组条形的中心都会完美重合。

示例代码:

import pandas as pd
import matplotlib.pyplot as plt

# 模拟你的数据
df_group1 = pd.DataFrame({'category': ['cat1', 'cat2'], 'value': [3, 5]})
df_group2 = pd.DataFrame({'category': ['cat1', 'cat2'], 'value': [4, 2]})

fig, ax_bottom = plt.subplots(figsize=(8, 5))

# 绘制底部x轴的条形,宽度0.4,居中对齐
bars_bottom = ax_bottom.bar(
    df_group1['category'], 
    df_group1['value'], 
    width=0.4, 
    color='black', 
    align='center',
    label='Group 1'
)

# 创建顶部x轴
ax_top = ax_bottom.twiny()

# 绘制顶部x轴的条形,宽度0.2,同样居中对齐
bars_top = ax_top.bar(
    df_group2['category'], 
    df_group2['value'], 
    width=0.2, 
    color='#ff4444', 
    align='center',
    label='Group 2'
)

# 添加图例和标签,让图表更清晰
ax_bottom.set_ylabel('Group 1 Value')
ax_top.set_ylabel('Group 2 Value')
ax_bottom.legend(loc='upper left')
ax_top.legend(loc='upper right')

plt.tight_layout()
plt.show()

这样调整后,不管你把两组条形的宽度改成多少,它们都会始终以分类中心为基准重叠,完美对齐。

方法二:手动计算中心位置(适合已用默认对齐的场景)

如果你已经用了默认的align='edge',不想修改这个设置,可以手动计算第一组条形的中心位置,然后调整第二组条形的x坐标,让它的中心和第一组重合:

import pandas as pd
import matplotlib.pyplot as plt

df_group1 = pd.DataFrame({'category': ['cat1', 'cat2'], 'value': [3, 5]})
df_group2 = pd.DataFrame({'category': ['cat1', 'cat2'], 'value': [4, 2]})

fig, ax_bottom = plt.subplots(figsize=(8, 5))

# 绘制底部条形(默认左对齐)
bars_bottom = ax_bottom.bar(
    df_group1['category'], 
    df_group1['value'], 
    width=0.4, 
    color='black',
    label='Group 1'
)

# 计算底部条形的中心位置
bar_centers = [bar.get_x() + bar.get_width()/2 for bar in bars_bottom]

# 创建顶部x轴
ax_top = ax_bottom.twiny()

# 绘制顶部条形,x坐标设置为底部条形的中心减去自身宽度的一半
bars_top = ax_top.bar(
    [center - 0.2/2 for center in bar_centers],  # 0.2是顶部条形的宽度
    df_group2['value'], 
    width=0.2, 
    color='#ff4444',
    label='Group 2'
)

# 同步顶部x轴的刻度位置和标签
ax_top.set_xticks(bar_centers)
ax_top.set_xticklabels(df_group2['category'])

# 添加图例和标签
ax_bottom.set_ylabel('Group 1 Value')
ax_top.set_ylabel('Group 2 Value')
ax_bottom.legend(loc='upper left')
ax_top.legend(loc='upper right')

plt.tight_layout()
plt.show()

这个方法的核心是通过bar.get_x()获取条形左边缘位置,加上宽度的一半得到中心,再让顶部条形的左边缘位置等于中心减去自身宽度的一半,这样两者的中心就完全重合了。


内容的提问来源于stack exchange,提问作者BoroBorooooooooooooooooooooooo

火山引擎 最新活动