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

求助:如何用Matplotlib绘制共享X轴的多分组数据图表?

调整Matplotlib代码以生成按API分组的预期多子图时间序列图表

我想要绘制类似示例图的多子图时间序列图表,目前编写了代码但没得到预期效果,当前生成的图表和按Server分组的图表也不符合需求,希望得到指导。

我当前的代码:

import matplotlib.pyplot as plt
import pandas as pd

data_set= [
    {'date':'2018-05-20','server':'server1','api':'api1','count':4},
    {'date':'2018-05-21','server':'server1','api':'api1','count':6},
    {'date':'2018-05-22','server':'server1','api':'api1','count':10},
    {'date':'2018-05-23','server':'server1','api':'api1','count':10},
    {'date':'2018-05-24','server':'server1','api':'api1','count':14},
    {'date':'2018-05-20','server':'server1','api':'api2','count':20},
    {'date':'2018-05-21','server':'server1','api':'api2','count':22},
    {'date':'2018-05-22','server':'server1','api':'api2','count':20},
    {'date':'2018-05-23','server':'server1','api':'api2','count':23},
    {'date':'2018-05-24','server':'server1','api':'api2','count':20},
    {'date':'2018-05-24','server':'server2','api':'api1','count':30},
    {'date':'2018-05-21','server':'server2','api':'api2','count':20}
]

f, (axs) = plt.subplots(3, sharex=True, sharey=True)
df = pd.DataFrame(data_set)
df['date'] = pd.to_datetime(df['date'],format='%Y/%m/%d %H:%M:%S')
df = df.set_index('date')
grouped = df.groupby(['api'])

for (name, df1), ax in zip(grouped, axs.flat):
    df1.plot(y='count', ax=ax)

plt.legend(bbox_to_anchor=(1, 1, 0.25, -0.2), bbox_transform=plt.gcf().transFigure)
f.subplots_adjust(hspace=0)
plt.setp([a.get_xticklabels() for a in f.axes[:-1]], visible=False)

问题分析:

  1. 日期解析格式错误:原数据的date是YYYY-MM-DD格式,但代码里用了%Y/%m/%d %H:%M:%S,虽然后续Pandas可能自动兼容,但规范匹配格式能避免潜在问题
  2. 子图数量不匹配:API只有api1和api2两个分组,但创建了3个子图,会多出一个空图
  3. 未按Server区分线条:每个API子图里没有拆分不同Server的数据,导致所有数据画成一条线,无法区分不同服务器的表现
  4. 图例设置不合理:全局图例没有对应到正确的Server标识,显示混乱

修正后的代码:

import matplotlib.pyplot as plt
import pandas as pd

data_set= [
    {'date':'2018-05-20','server':'server1','api':'api1','count':4},
    {'date':'2018-05-21','server':'server1','api':'api1','count':6},
    {'date':'2018-05-22','server':'server1','api':'api1','count':10},
    {'date':'2018-05-23','server':'server1','api':'api1','count':10},
    {'date':'2018-05-24','server':'server1','api':'api1','count':14},
    {'date':'2018-05-20','server':'server1','api':'api2','count':20},
    {'date':'2018-05-21','server':'server1','api':'api2','count':22},
    {'date':'2018-05-22','server':'server1','api':'api2','count':20},
    {'date':'2018-05-23','server':'server1','api':'api2','count':23},
    {'date':'2018-05-24','server':'server1','api':'api2','count':20},
    {'date':'2018-05-24','server':'server2','api':'api1','count':30},
    {'date':'2018-05-21','server':'server2','api':'api2','count':20}
]

# 1. 正确解析日期格式
df = pd.DataFrame(data_set)
df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d')
df = df.set_index('date')

# 2. 按API分组,获取实际分组数量
api_groups = df.groupby(['api'])
num_groups = len(api_groups)

# 3. 根据分组数量动态创建子图,避免空图
fig, axs = plt.subplots(num_groups, sharex=True, sharey=True, figsize=(10, 6))
fig.suptitle('API Request Count by Server Over Time', y=1.02)

# 4. 遍历每个API分组,在对应子图内按Server绘制不同线条
for (api_name, api_df), ax in zip(api_groups, axs.flat):
    server_groups = api_df.groupby('server')
    for server_name, server_df in server_groups:
        server_df['count'].plot(ax=ax, label=server_name)
    ax.set_title(f'API: {api_name}')
    ax.legend(title='Server')
    ax.set_ylabel('Request Count')

# 5. 调整布局与x轴显示
fig.subplots_adjust(hspace=0.3)
plt.setp([a.get_xticklabels() for a in fig.axes[:-1]], visible=False)
plt.xlabel('Date')
plt.tight_layout()
plt.show()

修正说明:

  • 匹配了日期解析格式,确保数据处理准确
  • 动态生成子图数量,避免多余空图
  • 在每个API子图内按Server拆分数据绘制,清晰区分不同服务器的请求计数变化
  • 为每个子图添加标题和图例,提升图表可读性
  • 优化了整体布局和标签显示,让图表更美观专业

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:00:06