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

Seaborn绘图使用twinx()后x轴显示错位异常问题求助

问题原因与修复方案

核心错误原因

  • seaborn.barplot 属于分类图类型,无论传入的x轴字段dt_mvtc是字符串还是日期格式,都会自动将所有x值按出现顺序映射到0,1,2...n-1的整数位置,x轴本质是分类索引轴。
  • seaborn.lineplot 属于连续数值图类型,如果dt_mvtc是日期格式,会直接用日期对应的时间戳数值作为x坐标,和barplot的分类索引完全不匹配,因此出现标签错位。
  • 你观察到注释掉ax2 = ax.twinx()后x轴显示正常,是因为单轴绘图时不会触发两个不同坐标体系的冲突,问题根源并非twinx本身,而是两类图表的x坐标映射规则不统一。
  • 额外的代码不规范问题:调用plt.xticks、plt.xlabel这类全局pyplot方法时,默认作用于最后创建的轴也就是ax2,进一步加剧了x轴配置的混乱。

修复方案

提供两种常用适配方案,可根据需求选择:

方案1:强制lineplot使用和barplot一致的分类索引

适合需要保留seaborn barplot默认样式的场景,修改后代码如下:

from matplotlib.ticker import ScalarFormatter
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

fig, ax = plt.subplots(figsize=(20, 10))
ax2 = ax.twinx()

# 预筛选绘图数据集,避免多次query结果不一致
plot_df = df_grafico_merge.query('t0_def_qtt==1').reset_index(drop=True)

# 绘制barplot
sns.barplot(x="dt_mvtc", y="qtde_t0", data=plot_df, color='blue', ax=ax)
# 获取barplot的分类位置和标签
x_ticks = ax.get_xticks()
x_labels = [label.get_text() for label in ax.get_xticklabels()]

# 绘制lineplot时直接用barplot的位置作为x值,保证坐标完全对齐
sns.lineplot(x=x_ticks, y='qtde_t12', hue='t12_def_qtt', style='t12_def_qtt',
             data=plot_df, markers=True, color='orange', ax=ax2)

# 所有轴配置明确指定对应轴,避免全局调用混乱
ax.set_xlabel("Data")
ax.set_ylabel("Quantidade (柱状图)")
ax2.set_ylabel("Quantidade (折线图)")
ax.set_title('Qtde de registros por data e t0=1')
# 统一在主轴设置x轴刻度和旋转
ax.set_xticks(x_ticks)
ax.set_xticklabels(x_labels, rotation=90, ha='right')

formatter = ScalarFormatter()
formatter.set_scientific(True)
ax.yaxis.set_major_formatter(formatter)

plt.tight_layout()
plt.show()

方案2:使用原生matplotlib bar替代seaborn barplot

适合需要保留x轴日期连续属性的场景,修改后代码如下:

from matplotlib.ticker import ScalarFormatter
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

fig, ax = plt.subplots(figsize=(20, 10))
ax2 = ax.twinx()

plot_df = df_grafico_merge.query('t0_def_qtt==1').reset_index(drop=True)
# 原生bar支持连续日期作为x坐标,和lineplot坐标体系统一
ax.bar(x=plot_df['dt_mvtc'], height=plot_df['qtde_t0'], color='blue', width=0.7)

sns.lineplot(x="dt_mvtc", y='qtde_t12', hue='t12_def_qtt', style='t12_def_qtt',
             data=plot_df, markers=True, color='orange', ax=ax2)

ax.set_xlabel("Data")
ax.set_ylabel("Quantidade (柱状图)")
ax2.set_ylabel("Quantidade (折线图)")
ax.set_title('Qtde de registros por data e t0=1')
plt.setp(ax.get_xticklabels(), rotation=90, ha='right')

formatter = ScalarFormatter()
formatter.set_scientific(True)
ax.yaxis.set_major_formatter(formatter)

plt.tight_layout()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:45:07