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

Seaborn中基于日期X轴绘制柱状图与折线图(共享单Y轴)

解决方案:在Seaborn中共享日期X轴,单Y轴绘制柱状图+折线图

核心问题是Seaborn的barplot默认会把日期X轴当作离散类别处理,而lineplot则将日期视为连续轴,直接混用会导致轴对齐异常。以下是可行的实现步骤和代码:

实现步骤

  1. 确保数据中的日期列是datetime64[ns]类型(若未处理,可通过df['datetime'] = pd.to_datetime(df['datetime'])转换)。
  2. 先绘制折线图,以此确定唯一的Y轴基准(日均价格)。
  3. 将日期转换为matplotlib可识别的数值格式,让柱状图与折线图的X轴坐标完全对齐。
  4. 若销量与价格量级差异较大,需对销量数据进行缩放,使其适配价格Y轴的刻度范围。
  5. 调整柱状图宽度、日期标签格式,优化图表可读性。

完整代码示例

假设你的数据框名为df,包含datetime、num_sales、average_daily_price三列:

import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd

# 确保日期列格式正确(若未处理)
df['datetime'] = pd.to_datetime(df['datetime'])

# 创建画布与轴对象
fig, ax = plt.subplots(figsize=(10, 6))

# 先绘制折线图,以日均价格为Y轴基准
sns.lineplot(
    data=df,
    x='datetime',
    y='average_daily_price',
    ax=ax,
    color='#e74c3c',
    marker='o',
    linewidth=2
)

# 将日期转换为matplotlib数值格式,用于柱状图的X坐标
x_coords = mdates.date2num(df['datetime'])
# 设置柱状图宽度(根据日期间隔调整,这里设为0.5天)
bar_width = 0.5

# 缩放销量数据,使其适配价格Y轴的范围
scale_ratio = df['average_daily_price'].max() / df['num_sales'].max()
scaled_sales = df['num_sales'] * scale_ratio

# 绘制柱状图
ax.bar(
    x_coords,
    scaled_sales,
    width=bar_width,
    alpha=0.3,
    color='#3498db'
)

# 格式化X轴日期显示
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
# 自动旋转日期标签,避免重叠
fig.autofmt_xdate()

# 设置轴标签与标题
ax.set_xlabel('日期')
ax.set_ylabel('日均价格')
ax.set_title('日均价格与销量趋势')

# 添加图例,标注销量已缩放
ax.legend(['日均价格', '销量(已缩放)'])

plt.tight_layout()
plt.show()

关键说明

  • 为什么不用twinx():因为你不需要双Y轴,通过缩放销量数据,就能让柱状图与折线图共享同一个价格Y轴,同时保留销量的相对趋势。
  • 日期对齐的核心:用mdates.date2num()将日期转为数值,让柱状图的X坐标与折线图的连续日期轴完全匹配,解决了Seaborn两种绘图函数对日期轴的不同处理逻辑问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 20:40:29