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

如何在同一图表中绘制折线图与箱线图且X轴为日期及报错解决

问题解决方法

错误原因

  1. df2被定义为字典而非pandas.DataFrame,无法直接调用boxplot方法
  2. positions参数的长度与按month分组后的组数不匹配:你的df2包含5个月份(5-9月),但只传入了1个位置值,导致统计量和位置列表长度不一致

修正后的代码

import pandas as pd
from datetime import datetime
import matplotlib.pyplot as plt

# 处理df1:转换date列为datetime类型,确保X轴时序正确
df1 = pd.DataFrame({
    'date': ['2023-04-01', '2023-03-01', '2023-02-01', '2023-01-01', '2022-12-01'],
    'year': [2023,2023,2023,2023,2022],
    'month': [4,3,2,1,12],
    'discharge': [10, 20, 30, 15, 25]
})
df1['date'] = pd.to_datetime(df1['date'])

# 生成df2并转换为DataFrame
start_date = datetime(2023, 5, 1)
end_date = datetime(2023, 9, 1)
dates = pd.date_range(start=start_date, end=end_date, freq='MS')

df2 = pd.DataFrame({
    'date': dates.repeat(10),
    'year': [d.year for d in dates] * 10,
    'month': [d.month for d in dates] * 10,
    'discharge': [i+1 for i in range(len(dates))] * 10
})
df2['date'] = pd.to_datetime(df2['date'])

# 绘图
fig, ax = plt.subplots(figsize=(10,6))

# 绘制df1的折线图
ax.plot(df1['date'], df1['discharge'], label='单月流量', marker='o')

# 提取每个月份对应的日期数值(用于箱线图的X轴位置)
# 按month分组,取每组第一个date的matplotlib数值
grouped_dates = df2.groupby('month')['date'].first().apply(lambda x: x.toordinal())
# 绘制df2的箱线图,positions对应每个月份的X轴位置
df2.boxplot(column='discharge', by='month', positions=grouped_dates.values, 
            widths=15, ax=ax, patch_artist=True, label='月份流量分布')

# 设置X轴格式为日期
ax.xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y-%m'))
plt.xticks(rotation=45)

# 添加图例和标签
ax.set_ylabel('流量')
ax.set_xlabel('日期')
ax.legend()
plt.suptitle('')  # 去掉boxplot自动生成的标题
plt.tight_layout()
plt.show()

关键修正点

  • 将df2从字典转为pd.DataFrame,并统一转换date列为datetime类型,保证时序一致性
  • 提取每个月份对应的日期数值作为positions参数,确保分组数和位置数一致
  • 设置X轴日期格式化,提升图表可读性
  • 调整箱线图宽度,避免和折线图重叠

内容的提问来源于stack exchange,提问作者José R. Valles León

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:30:35