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

Seaborn合并barplot与lineplot时X轴显示异常问题求助

问题根源

X轴错位的核心原因是seaborn.barplot的X轴默认采用分类坐标体系:即使你传入的Year是数值年份,柱状图的每个柱对应的X坐标实际是从0开始的整数索引(1910对应0,1911对应1,……1920对应10),但你绘制折线图时用的是真实年份数值(1910~1920),两套坐标体系不匹配自然会错位。


修正方案

只需要将折线图的X值映射到柱状图的分类索引坐标体系即可,修改逻辑如下:

  1. 将插值生成的X_(真实年份)转换为对应的分类索引:X_ - dfGroup['Year'].min()
  2. 手动设置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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 08:48:03