使用twinx()绘制Seaborn折线图与柱状图仅显示柱状图问题
问题解决:双轴图表中折线图不显示的问题
问题背景
拥有如下数据集:
Year Average Mi Gasoline 0 2022 336.714286 4.00 1 2021 259.674419 2.84 2 2020 280.342105 2.25 3 2019 219.228571 2.67 5 2018 187.083333 2.72 4 2017 166.900000 2.33 6 2016 145.096774 2.17 7 2015 137.388889 2.44 8 2014 114.800000 3.46 9 2013 906.142857 3.44 10 2012 90.111111 3.63 14 2011 53.250000 3.46 11 2008 90.000000 3.37 12 2003 65.000000 1.54 13 2002 76.500000 1.35 16 2001 57.600000 1.46 15 2000 63.250000 1.57
想要在同一图表中,以Year为X轴,用柱状图展示Average Mi数据,折线图展示Gasoline数据,使用代码:
fig, ax = plt.subplots(figsize=(12, 6)) sns.lineplot(data=df, x='Year', y='Gasoline', marker='o', sort=False, color='red', ax=ax) ax2= ax.twinx() sns.barplot(data=df, x='Year', y='Average Mi', alpha=0.5, ax=ax2)
单独绘制两个图表都能正常显示,但同时运行代码时,仅显示柱状图,折线图不出现。
原因分析
核心问题是两个图表的X轴顺序不匹配:
sns.lineplot设置了sort=False,会严格按照数据集中Year的原始顺序绘制折线sns.barplot默认会对X轴的数值型/类别型变量进行升序排序,导致柱状图的X轴顺序是从2000到2022,和折线图的原始数据顺序完全不一致- 当使用
twinx()创建双轴后,第二个轴(柱状图)的X轴覆盖了第一个轴的显示范围,折线图的点对应不上新的X轴刻度,因此被隐藏
解决方法
方法1:先对数据集按Year排序(推荐)
先将数据按Year从旧到新排序,确保两个图表的X轴顺序一致:
# 按Year升序排序 df_sorted = df.sort_values('Year') fig, ax = plt.subplots(figsize=(12, 6)) # 使用排序后的数据集绘制折线图 sns.lineplot(data=df_sorted, x='Year', y='Gasoline', marker='o', color='red', ax=ax) ax2 = ax.twinx() # 使用排序后的数据集绘制柱状图 sns.barplot(data=df_sorted, x='Year', y='Average Mi', alpha=0.5, ax=ax2) # 可选:添加标签提升可读性 ax.set_ylabel('Gasoline Price') ax2.set_ylabel('Average Miles') plt.title('Gasoline Price vs Average Miles by Year') plt.show()
方法2:强制柱状图使用原始数据的Year顺序
在sns.barplot中指定order参数,保持和数据集原始顺序一致:
fig, ax = plt.subplots(figsize=(12, 6)) sns.lineplot(data=df, x='Year', y='Gasoline', marker='o', sort=False, color='red', ax=ax) ax2 = ax.twinx() # 指定order为df中Year的原始顺序 sns.barplot(data=df, x='Year', y='Average Mi', alpha=0.5, ax=ax2, order=df['Year']) ax.set_ylabel('Gasoline Price') ax2.set_ylabel('Average Miles') plt.title('Gasoline Price vs Average Miles by Year') plt.show()
方法3:将Year转换为字符串类型
把Year列转为字符串,避免sns.barplot自动排序数值型变量:
df['Year'] = df['Year'].astype(str) fig, ax = plt.subplots(figsize=(12, 6)) sns.lineplot(data=df, x='Year', y='Gasoline', marker='o', sort=False, color='red', ax=ax) ax2 = ax.twinx() sns.barplot(data=df, x='Year', y='Average Mi', alpha=0.5, ax=ax2) ax.set_ylabel('Gasoline Price') ax2.set_ylabel('Average Miles') plt.title('Gasoline Price vs Average Miles by Year') plt.xticks(rotation=45) # 旋转X轴标签避免重叠 plt.show()
内容的提问来源于stack exchange,提问作者Sanborn Nguyen
相关产品推荐
相关产品推荐

