如何在matplotlib.pyplot.table的单元格中插入图片替换文本内容
问题描述
现有如下代码,基于matplotlib绘制带底部表格的散点图:
import os, sys import numpy as np import matplotlib.pyplot as plt N = 20 x = 0.5 * np.random.rand(N) y1 = 0.2 * np.random.rand(N) y2 = 0.2 * np.random.rand(N) plt.scatter(x, y1, marker='*') plt.scatter(x, y2, marker='x') cell_text = [ ['2020-05-05', '2020-08-25', '2020-09-01', '2020-10-21', '2020-11-03' ], ['08:05:10', '19:32:50', '22:55:13', '15:00:00', '09:41:42'], ['sun', 'rain', 'night', 'overcast', 'sun'] ] cols = ['Test01', 'Test02', 'Test03', 'Test04', 'Test05'] rows = ["Date","Time[GMT]","Weather"] the_table = ax.table(cellText=cell_text, cellLoc = 'center', rowLabels=rows, rowColours=None, colLabels=cols, loc='bottom') the_table.scale(1, 3) ax.set_xticklabels([]) plt.show()
生成的图表为带底部表格的散点图,表格包含日期、时间、天气三类数据。
需求是将表格中Weather行的文本替换为本地存储的对应天气表情图片,原尝试直接给单元格文本对象赋值图片数组的方法不生效,仅修改文本内容可正常运行,询问正确的图片插入实现方式。
解决方案
核心原因:matplotlib的Table组件仅原生支持文本内容,无法直接将图片赋值给文本对象实现替换,需要通过自定义标注的方式将图片嵌入到单元格对应位置。
完整可运行实现代码如下:
import os, sys import numpy as np import matplotlib.pyplot as plt from matplotlib.offsetbox import OffsetImage, AnnotationBbox # 基础绘图逻辑 N = 20 x = 0.5 * np.random.rand(N) y1 = 0.2 * np.random.rand(N) y2 = 0.2 * np.random.rand(N) # 补全原代码遗漏的轴对象定义 fig, ax = plt.subplots() ax.scatter(x, y1, marker='*') ax.scatter(x, y2, marker='x') cell_text = [ ['2020-05-05', '2020-08-25', '2020-09-01', '2020-10-21', '2020-11-03' ], ['08:05:10', '19:32:50', '22:55:13', '15:00:00', '09:41:42'], ['sun', 'rain', 'night', 'overcast', 'sun'] ] cols = ['Test01', 'Test02', 'Test03', 'Test04', 'Test05'] rows = ["Date","Time[GMT]","Weather"] the_table = ax.table(cellText=cell_text, cellLoc = 'center', rowLabels=rows, rowColours=None, colLabels=cols, loc='bottom') the_table.scale(1, 3) ax.set_xticklabels([]) # 插入表情图片核心逻辑 emoji_dataset = os.path.join(os.environ['HOME'], 'Datasets', 'Emojis') for ci in range(len(cols)): # 获取Weather行对应单元格,行号规则:表头行索引为0,Date为1、Time为2、Weather为3 cell = the_table.get_celld()[(3, ci)] # 隐藏原有文本内容 cell.get_text().set_visible(False) # 读取对应天气表情图 weather_type = cell_text[2][ci] img = plt.imread(os.path.join(emoji_dataset, f"{weather_type}.png")) # 构造图片对象,zoom参数控制缩放比例,可根据单元格大小调整 image_box = OffsetImage(img, zoom=0.15) image_box.image.axes = ax # 计算单元格中心点坐标 cell_extent = cell.get_window_extent(renderer=fig.canvas.get_renderer()) cell_center = ax.transData.inverted().transform_point((cell_extent.x0 + cell_extent.width/2, cell_extent.y0 + cell_extent.height/2)) # 将图片嵌入到单元格中心位置 ab = AnnotationBbox(image_box, cell_center, frameon=False) ax.add_artist(ab) # 调整底部留白,避免表格被截断 plt.subplots_adjust(bottom=0.3) plt.show()
调整说明
- 可根据实际单元格高度修改
zoom参数,匹配表情图的显示大小 - 可根据表格实际高度调整
subplots_adjust的bottom参数,预留足够的底部显示空间
内容的提问来源于stack exchange,提问作者farid
相关产品推荐
相关产品推荐

