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

Telegram Python机器人函数绘图报错求助:Matplotlib维度不匹配

问题分析

你遇到两个核心问题:

  • 维度不匹配错误:message.text是用户发送的字符串(比如"x**2"),直接赋值给y的话,它是长度为1的字符串对象,而x是长度100的numpy数组,plt.plot要求x和y维度一致,因此报错。
  • Matplotlib线程警告:telebot的polling默认用多线程运行,Matplotlib默认GUI后端在子线程中会触发警告甚至报错,需要切换到非交互式后端。

解决方案

1. 安全计算用户输入的函数表达式

不能直接用eval执行用户输入的字符串(存在恶意代码风险),需要限定允许使用的变量和函数,只开放numpy数学函数与x变量。

2. 切换Matplotlib后端

在导入matplotlib.pyplot前,设置非交互式后端Agg,彻底规避GUI线程问题。

3. 完善代码逻辑

  • 基于x数组计算y值,确保维度匹配
  • 绘图后及时清理资源,避免内存泄漏
  • 添加错误捕获,处理用户输入非法表达式的情况

修改后的完整代码

import telebot
import matplotlib
# 切换到非交互式后端,解决线程警告问题
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np

# 替换为你的机器人Token
bot = telebot.TeleBot("YOUR_BOT_TOKEN")

def plot_func(message, func_str):
    try:
        x = np.linspace(-5, 5, 100)
        # 限定命名空间,仅允许安全的变量和函数
        allowed_namespace = {
            'x': x,
            'np': np,
            'sin': np.sin,
            'cos': np.cos,
            'tan': np.tan,
            'exp': np.exp,
            'log': np.log,
            'sqrt': np.sqrt
        }
        # 计算y值
        y = eval(func_str, {"__builtins__": None}, allowed_namespace)
        
        # 绘图并保存
        plt.figure(figsize=(6,4))
        plt.plot(x, y, 'r', linewidth=2)
        plt.xlabel('x')
        plt.ylabel('y')
        plt.title(f'$y = {func_str}$', fontsize=12)
        plt.grid(alpha=0.3)
        
        plt.savefig('plot_temp.png', dpi=300, bbox_inches='tight')
        plt.close()  # 关闭绘图,释放内存
        
        # 发送图片
        with open('plot_temp.png', 'rb') as photo:
            bot.send_photo(message.chat.id, photo=photo)
    
    except Exception as e:
        bot.reply_to(message, f"表达式错误:{str(e)}")

# 注册/plot命令,用户输入格式:/plot x**2
@bot.message_handler(commands=['plot'])
def handle_plot_command(message):
    func_str = message.text[len('/plot'):].strip()
    if not func_str:
        bot.reply_to(message, "请输入函数表达式,示例:/plot x**2 或 /plot np.sin(x)")
        return
    plot_func(message, func_str)

# 启动机器人
bot.polling(none_stop=True)

关键说明

  • 安全防护:通过{"__builtins__": None}禁用所有内置函数,仅开放指定的numpy函数和x变量,避免用户执行恶意代码。
  • 后端设置:matplotlib.use('Agg')必须在导入plt前调用,确保非交互式后端生效。
  • 资源管理:plt.close()每次绘图后关闭画布,防止内存中堆积大量未释放的绘图对象。
  • 错误处理:捕获所有异常并反馈给用户,避免机器人因非法输入崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:30:48