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

如何用Matplotlib将Pandas GroupBy结果绘制成并排折线图与柱状图?

问题

现有一个包含多列的DataFrame,希望将通过Pandas GroupBy分组后的结果,在同一张图片中并排展示折线图(呈现Score列数据)与柱状图(呈现Thumbs-up列数据)。目前编写的代码会生成两个独立的图表,无法实现同图并排的效果,请问使用Matplotlib如何正确实现该需求?

当前尝试的代码如下:

import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from io import StringIO

csvfile = StringIO(
"""
Name    Year - Month    Score   Thumbs-up
Mike    2022-09 192 5
Mike    2022-08 708 5
Mike    2022-07 140 3
Mike    2022-05 144 8
Mike    2022-04 60  10
Mike    2022-03 108 4
Kate    2022-07 19850   5
Kate    2022-06 19105   2
Kate    2022-05 23740   3
Kate    2022-04 19780   9
Kate    2022-03 15495   4 """
)

df = pd.read_csv(csvfile, sep = '\t', engine='python')

for group_name, sub_frame in df.groupby("Name"):

    fig, axes = plt.subplots(nrows=1,ncols=2,figsize=(12,6))

    sub_frame_sorted = sub_frame.sort_values('Year - Month')       # sort the data-frame by a column

    line_chart = sub_frame_sorted.plot("Year - Month", "Score", legend=False)
    bar_chart = sub_frame_sorted.plot.bar("Year - Month", "Thumbs-up", legend=False)

    # for data labeling in the charts
    i=0
    for ix, vl in sub_frame_sorted.iterrows():
        line_chart.annotate(vl['Score'], (i, vl['Score']), ha='center')
        bar_chart.annotate(vl['Thumbs-up'], (i, vl['Thumbs-up']), ha='center')
        i=i+1

    plt.show()

解决方法

问题出在你没给Pandas绘图指定具体的Matplotlib子图轴,每次调用plot都会自动创建新图表。只要把plt.subplots生成的子图轴对象传给plot的ax参数,就能让折线图和柱状图并排显示在同一张画布上。

修正后的完整代码:

import matplotlib.pyplot as plt
import pandas as pd
from io import StringIO

csvfile = StringIO(
"""
Name    Year - Month    Score   Thumbs-up
Mike    2022-09 192 5
Mike    2022-08 708 5
Mike    2022-07 140 3
Mike    2022-05 144 8
Mike    2022-04 60  10
Mike    2022-03 108 4
Kate    2022-07 19850   5
Kate    2022-06 19105   2
Kate    2022-05 23740   3
Kate    2022-04 19780   9
Kate    2022-03 15495   4 """
)

df = pd.read_csv(csvfile, sep='\t', engine='python')

for group_name, sub_frame in df.groupby("Name"):
    # 创建1行2列的子图布局,获取两个轴对象
    fig, (ax_line, ax_bar) = plt.subplots(nrows=1, ncols=2, figsize=(12, 6))
    
    sub_frame_sorted = sub_frame.sort_values('Year - Month')
    
    # 将折线图绘制到第一个子图轴ax_line上
    sub_frame_sorted.plot(x="Year - Month", y="Score", kind='line', legend=False, ax=ax_line)
    # 将柱状图绘制到第二个子图轴ax_bar上
    sub_frame_sorted.plot(x="Year - Month", y="Thumbs-up", kind='bar', legend=False, ax=ax_bar)
    
    # 为折线图添加数据标注
    for i, vl in enumerate(sub_frame_sorted['Score']):
        ax_line.annotate(str(vl), (i, vl), ha='center', va='bottom')
    
    # 为柱状图添加数据标注
    for i, vl in enumerate(sub_frame_sorted['Thumbs-up']):
        ax_bar.annotate(str(vl), (i, vl), ha='center', va='bottom')
    
    # 为子图添加标题,区分不同分组
    ax_line.set_title(f"{group_name} - Score Trend")
    ax_bar.set_title(f"{group_name} - Thumbs-up Count")
    
    # 调整子图间距,避免标签重叠
    plt.tight_layout()
    plt.show()

关键改动点

  • 绑定子图轴:通过ax参数把折线图、柱状图分别指定到预先创建的两个子图上,确保它们在同一张图里。
  • 优化标注逻辑:用enumerate遍历数据,替代手动计数,代码更简洁。
  • 添加子图标题:给每个子图加上对应分组的标题,直观区分内容。
  • 自动调整布局:调用tight_layout()避免标签、标题互相遮挡。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 18:15:14