如何在同一画布中匹配pandas分组箱线图与DataFrame折线图?脚本问题求助
如何在同一画布中匹配pandas分组箱线图与DataFrame折线图?脚本问题求助
嘿,我来帮你排查这个问题!你的脚本没法把两个图正确叠加显示,核心问题出在x轴的类型不匹配上:
- 你用
lambda x: x.strftime("%Y-%m-%d")做分组键,生成的箱线图x轴是字符串格式的日期(比如"2014-02-01"); - 而
ts.plot()默认用原DataFrame的datetime64类型时间戳索引作为x轴。
这两种x轴刻度的底层类型完全不一样,matplotlib没办法把它们对齐到同一坐标轴上,最后要么只显示其中一个图,要么两个图错位到完全看不到彼此。
下面给你两个可行的解决办法:
方案一:最简单的修复——用日期对象分组(推荐)
直接把分组键换成ts.index.date,这样箱线图的x轴会是datetime.date类型,和原时间序列的索引类型兼容,matplotlib能自动对齐两个图的x轴:
import pandas as pd import numpy as np import matplotlib.pyplot as plt fig, axes = plt.subplots(1, 1, figsize=(15, 15)) n = 480 ts = pd.DataFrame(np.random.randn(n), index=pd.date_range(start="2014-02-01",periods=n,freq="H")) # 重点:用index.date作为分组键,而非转成字符串 ts.groupby(ts.index.date).boxplot(subplots=False, rot=90, ax=axes) ts.plot(ax=axes) # 把x轴标签格式化成清晰的日期字符串 axes.xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y-%m-%d')) plt.tight_layout() plt.show()
修改后,箱线图的每个箱体对应一天的位置,折线图的小时级数据点会自动对齐到对应的日期x轴上,完美叠加!
方案二:手动映射x轴位置(更灵活)
如果你一定要用字符串格式的日期作为箱线图标签,可以手动把折线图的x轴位置映射到箱线图的刻度位置上,适合需要自定义x轴布局的场景:
import pandas as pd import numpy as np import matplotlib.pyplot as plt fig, axes = plt.subplots(1, 1, figsize=(15, 15)) n = 480 ts = pd.DataFrame(np.random.randn(n), index=pd.date_range(start="2014-02-01",periods=n,freq="H"), columns=['val']) # 1. 生成分组箱线图,获取轴对象和刻度信息 groups = ts.groupby(lambda x: x.strftime("%Y-%m-%d")) box_ax = groups.boxplot(subplots=False, rot=90, ax=axes, return_type='axes') box_labels = [tick.get_text() for tick in box_ax.get_xticklabels()] box_positions = np.arange(1, len(box_labels)+1) # 2. 给原数据添加日期列和对应的箱线图x轴位置 ts['date_str'] = ts.index.strftime("%Y-%m-%d") date_to_pos = {date: pos for date, pos in zip(box_labels, box_positions)} ts['x_pos'] = ts['date_str'].map(date_to_pos) # 3. 用matplotlib直接画折线图,基于箱线图的x轴位置 axes.plot(ts['x_pos'], ts['val'], label='Hourly Series') # 4. 保持箱线图的x轴标签样式 axes.set_xticks(box_positions) axes.set_xticklabels(box_labels, rotation=90) axes.legend() plt.tight_layout() plt.show()
备注:内容来源于stack exchange,提问作者user3046026
相关产品推荐
相关产品推荐

