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

Matplotlib添加第三个子图报错ValueError: num必须1≤num≤2而非3求解

解决Matplotlib子图布局导致的ValueError问题

嘿,这个问题我一眼就看出来了——你遇到的ValueError: num must be 1 <= num <= 2, not 3完全是因为子图的网格布局设置和分类数量不匹配。

问题根源

你用xox = '21{0}'.format(i)生成子图编号,这个编号的规则是行数+列数+子图索引,也就是说211代表2行1列布局里的第1个子图,212是第2个。这种布局最多只能放2个子图,当你加入第三个分类时,i变成3,生成的213就超出了这个布局的容纳范围,Matplotlib自然就报错了。

快速修复方案

最简单的办法是根据你要展示的分类数量,动态调整子图布局。比如你现在有3个分类,可以改成3行1列的布局(编号用31i),但更优雅的方式是用Matplotlib的plt.subplots直接创建对应数量的子图数组,这样完全不用手动计算子图编号,代码也更清晰。

修改后的完整代码

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import style

# 保留你原有的统计函数(加了ti的初始化,避免潜在的未定义问题)
def time_stamp_count(category):
    tst = []
    for i in cc_key_val_num:
        ti = None  # 提前初始化ti,防止后续报错
        for k,v in i.items():
            if k == 'Time':
                ti = v[:-2]
                tst.append({ti:0})
            if k == 'LIWC_lib':
                for x in v:
                    z,q = x
                    if z == category:
                        tst.pop()
                        tst.append({ti:q})
    return tst

style.use('dark_background')
# 注意这里你写了两个相同的focusfuture,可能是笔误,我保留原内容
category_name = ['focusfuture', 'focusfuture', 'focuspresent']
n_categories = len(category_name)

# 直接创建对应数量的子图:n行1列,figsize保持你的设置
fig, axes = plt.subplots(n_categories, 1, figsize=(16, 10))

def create_plots(xan):
    xs = []
    ys = []
    for i in xan:
        for k,v in i.items():
            xs.append(k)
            ys.append(v)
    return xs,ys

# 遍历子图和分类名称,一一对应绘制
for ax, step in zip(axes, category_name):
    xan = time_stamp_count(step)
    x,y = create_plots(xan)
    x_freq = 15
    x_axis = range(len(x))
    my_xticks = np.array(x)
    
    # 用面向对象的方式设置刻度,比plt.xticks更适合多子图场景
    ax.set_xticks(x_axis[::x_freq])
    ax.set_xticklabels(my_xticks[::x_freq])
    
    ax.plot(x_axis,y, label=step, color='#1dcaff')
    ax.legend()  # 每个子图单独加图例,更清晰

# 自动调整子图间距,避免标签重叠
plt.tight_layout()
plt.show()

额外优化建议

  1. 如果想改成横向排列(1行3列),只需要把plt.subplots(n_categories, 1)改成plt.subplots(1, n_categories)就行。
  2. 你原代码里的category_name有两个相同的focusfuture,可能是测试时的笔误,记得后续换成真实的分类名称。
  3. 用ax.set_xticks替代plt.xticks是更规范的面向对象写法,在多子图场景下不容易出现混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:48:40