You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 08:40:41