如何将Matplotlib savefig生成的图片发送至Python Telegram Bot?
解决Matplotlib生成图片通过Telegram Bot发送的问题
看了你的代码,我发现几个关键问题需要修正,才能顺利把Matplotlib生成的图片发送给用户。下面是完整的解决方案,我会一步步说明:
核心问题分析
- 缺少Matplotlib的导入,
plt.savefig会直接报错; - 没有从
message对象中获取正确的chat_id; - 生成图片的函数没有被调用,根本不会生成图片文件;
sendPhoto(TeleBot实际方法是send_photo)的参数传递不正确,需要传入图片的文件对象或有效路径。
完整修正代码
import telebot from flask import Flask, request import matplotlib.pyplot as plt from io import BytesIO # 可选,用于内存生成图片,无需存本地 token = '9542...................ke8nT10' URL = 'http://re......here.com/' bot = telebot.TeleBot(token, threaded=False) bot.remove_webhook() bot.set_webhook(url=URL) app = Flask(__name__) @app.route('/', methods=['POST']) def webhook(): update = telebot.types.Update.de_json(request.stream.read().decode('utf-8')) bot.process_new_updates([update]) return 'ok', 200 def generate_plot(): # 替换成你自己的绘图逻辑,这里是示例代码 plt.plot([1, 2, 3, 4], [1, 4, 9, 16]) plt.xlabel('X轴') plt.ylabel('Y轴') plt.title('示例图表') # 方式1:保存到本地文件(适合简单场景) # plt.savefig('plot_name.png', dpi=300) # plt.close() # return 'plot_name.png' # 方式2:内存生成(推荐,无需本地文件,避免文件覆盖) img_buffer = BytesIO() plt.savefig(img_buffer, dpi=300, format='png') img_buffer.seek(0) # 将文件指针移到开头,方便Bot读取 plt.close() # 关闭绘图释放内存,避免泄漏 return img_buffer @bot.message_handler(commands=['start']) def start_command(message): chat_id = message.chat.id # 从用户消息中获取聊天ID # 生成图片 img_source = generate_plot() # 发送图片给用户 bot.send_photo(chat_id=chat_id, photo=img_source) if __name__ == '__main__': # 根据服务器配置调整host和端口 app.run(host='0.0.0.0', port=8080)
关键细节说明
- 绘图逻辑补充:我把原来的
code()改名为generate_plot(),并添加了示例绘图代码——你必须在这里替换成自己的Matplotlib绘图逻辑,否则生成的图片会是空的。 - 两种图片生成方式:
- 本地文件:适合测试或低并发场景,但要确保服务器当前目录有写入权限,同时注意多用户请求时的文件覆盖问题;
- 内存生成(推荐):用
BytesIO把图片直接存在内存中,不需要写入本地文件,更高效也避免了文件管理的麻烦。
- 关闭绘图:每次绘图后调用
plt.close()很重要,能避免Matplotlib的内存泄漏问题,尤其是在高频请求的Bot中。 - Webhook环境注意:如果Bot部署在云服务器上,要确保Flask的
host设为0.0.0.0,端口与Webhook URL配置一致,同时服务器防火墙要开放对应端口。
内容的提问来源于stack exchange,提问作者Raja Sekhar Reddy Evuri




