Seaborn合并barplot与lineplot时X轴显示异常问题求助
问题根源
X轴错位的核心原因是seaborn.barplot的X轴默认采用分类坐标体系:即使你传入的Year是数值年份,柱状图的每个柱对应的X坐标实际是从0开始的整数索引(1910对应0,1911对应1,……1920对应10),但你绘制折线图时用的是真实年份数值(1910~1920),两套坐标体系不匹配自然会错位。
修正方案
只需要将折线图的X值映射到柱状图的分类索引坐标体系即可,修改逻辑如下:
- 将插值生成的X_(真实年份)转换为对应的分类索引:
X_ - dfGroup['Year'].min() - 手动设置X轴刻度标签为真实年份,保证展示正常
完整修正代码:
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt from scipy.interpolate import make_interp_spline dfGroup = pd.DataFrame({ 'Year': [1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, 1920], 'Total Deaths': [0, 0, 2, 3, 2, 3, 4, 5, 6, 7, 8], 'Total Affected': [0, 1, 0, 2, 3, 6, 9, 8, 12, 13, 15] }) # 计算3年移动平均 dfGroup['rolling_3years'] = dfGroup['Total Deaths'].rolling(3).mean().shift(0) dfGroup = dfGroup.fillna(0) # 生成平滑折线数据 X_Y_Spline = make_interp_spline(dfGroup['Year'], dfGroup['rolling_3years']) X_ = np.linspace(dfGroup['Year'].min(), dfGroup['Year'].max(), 500) Y_ = X_Y_Spline(X_) # 绘图 a4_dims = (15, 10) fig, ax1 = plt.subplots(figsize=a4_dims) # 绘制柱状图 sns.barplot(x = "Year", y = "Total Deaths", data = dfGroup, color='#42b7bd', ax=ax1) # 双轴绘制折线图,X值转换为分类索引 ax2 = ax1.twinx() # 核心修改:将真实年份转换为柱状图对应的索引坐标 sns.lineplot(x=X_ - dfGroup['Year'].min(), y=Y_, marker='o', ax=ax2, color='crimson') # 设置X轴刻度标签为真实年份 ax1.set_xticks(range(len(dfGroup['Year']))) ax1.set_xticklabels(dfGroup['Year']) # 补充轴标签方便辨识 ax1.set_ylabel('总死亡人数') ax2.set_ylabel('3年移动平均值') plt.show()
简化替代方案
如果不需要高度平滑的折线,完全可以跳过插值步骤,直接用原始移动平均数据绘制,代码更简洁也不会出现错位问题:
# 省略前面数据处理和移动平均计算部分 a4_dims = (15, 10) fig, ax1 = plt.subplots(figsize=a4_dims) sns.barplot(x = "Year", y = "Total Deaths", data = dfGroup, color='#42b7bd', ax=ax1) ax2 = ax1.twinx() # 直接用索引作为X值绘制移动平均线 sns.lineplot(x=range(len(dfGroup)), y=dfGroup['rolling_3years'], ax=ax2, color='crimson', linewidth=2) ax1.set_xticks(range(len(dfGroup['Year']))) ax1.set_xticklabels(dfGroup['Year']) ax1.set_ylabel('总死亡人数') ax2.set_ylabel('3年移动平均值') plt.show()
内容的提问来源于stack exchange,提问作者CrossLord
相关产品推荐
相关产品推荐

