Python开发Discord足球机器人:如何在Matplotlib表格中添加队徽?
在Matplotlib联赛排名表格中嵌入球队队徽
Matplotlib表格本身不支持直接插入图片,需要手动在对应单元格位置绘制加载好的队徽图片。结合你的现有流程,完整实现方案如下:
1. 准备依赖
确保安装所需库:
pip install pandas matplotlib pillow requests
2. 编写队徽加载函数
从API返回的URL下载图片并转为PIL Image对象,同时处理加载失败的异常情况:
import requests from PIL import Image, ImageDraw from io import BytesIO def load_team_badge(url): try: response = requests.get(url, timeout=5) response.raise_for_status() # 统一队徽尺寸,避免表格变形 return Image.open(BytesIO(response.content)).resize((30, 30)) except Exception: # 加载失败时生成灰色占位图 placeholder = Image.new('RGB', (30, 30), color='lightgray') draw = ImageDraw.Draw(placeholder) draw.text((10, 10), '?', fill='black') return placeholder
3. 生成带队徽的表格图片
假设你的Pandas DataFrame结构包含排名、球队名、积分、队徽URL列,直接复用现有数据即可:
import pandas as pd import matplotlib.pyplot as plt # 示例数据(替换为你的API返回数据) df = pd.DataFrame({ '排名': [1, 2, 3, 4], '球队名': ['曼城', '阿森纳', '利物浦', '热刺'], '积分': [85, 82, 79, 75], '队徽URL': ['https://example.com/man_city.png', 'https://example.com/arsenal.png', 'https://example.com/liverpool.png', 'https://example.com/tottenham.png'] }) # 创建画布,根据数据行数调整高度 fig, ax = plt.subplots(figsize=(8, len(df)*0.8)) ax.axis('off') # 隐藏坐标轴,只保留表格 # 绘制基础表格(包含队徽列标题) table = ax.table( cellText=df[['排名', '球队名', '积分']].values, colLabels=['排名', '球队名', '积分', '队徽'], cellLoc='center', loc='center' ) # 调整列宽,给队徽列预留空间 table.auto_set_column_width(col=list(range(4))) table.set_column_width(3, 0.15) # 遍历每一行,插入队徽 for i in range(len(df)): badge_img = load_team_badge(df['队徽URL'].iloc[i]) # 获取队徽单元格的坐标范围(表头行索引为0,数据行从1开始) cell = table.get_celld()[(i+1, 3)] # 将图片绘制到单元格位置 ax.imshow( badge_img, extent=[cell.get_x(), cell.get_x()+cell.get_width(), cell.get_y()-cell.get_height(), cell.get_y()] ) # 优化表格样式 table.auto_set_font_size(False) table.set_fontsize(12) table.scale(1.2, 1.5) # 缩放表格,提升可读性 # 保存到BytesIO对象(复用你已实现的逻辑) img_buffer = BytesIO() plt.savefig(img_buffer, format='png', bbox_inches='tight', dpi=150) img_buffer.seek(0) plt.close()
额外提示
如果要发送到Discord,直接将BytesIO对象传入discord.File即可:
from discord import File await channel.send(file=File(img_buffer, filename='league_ranking.png'))
内容的提问来源于stack exchange,提问作者Carl_Johnson
相关产品推荐
相关产品推荐

