Python与Matplotlib问题:循环第二次后表格尺寸异常
问题:Matplotlib循环刷新时表格被压缩且旧视图残留
我正在开发一款小型数字标牌应用,用Python+Matplotlib实现循环全屏显示数据柱状图及下方对应数据表格,实际应用中每次循环会从数据库拉取新数据(此功能已正常实现)。
问题表现:首次循环时柱状图与表格显示完全正常,但第二次及后续循环中,表格数据被压缩至约一半垂直空间,且旧视图仍可见。
原复现代码
import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np import pandas as pd # 顶部显示较大柱状图,下方显示较小数据表格 fig, (ax, ax_table) = plt.subplots(nrows = 2, gridspec_kw = dict(height_ratios = [7,1])) ax_table.axis('off') # 移除多余的图表坐标轴 mng = plt.get_current_fig_manager() mng.full_screen_toggle() # 切换至全屏显示 while(True): test_data = [["A","B","A","B","A","B","A","B","A","B"], [1,2,3,4,5,6,7,8,9,10], [100,200,300,400,500,600,700,800,900,1000], [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]] dfcon = pd.DataFrame(test_data) dfcon = dfcon.transpose() print('dfcon = ') print(dfcon) ax.cla() # 清除当前坐标轴(柱状图区域) ticks = np.arange(len(dfcon)) bar_width = 0.4 ax.set_xticks(ticks) ax.margins(x=0.01) # 按元素数量分配两侧边距,使柱状图与表格对齐 b1 = ax.bar(ticks , dfcon[1], width= -(bar_width), align = 'edge') # 负宽度使柱状图对齐刻度左侧 b2 = ax.bar(ticks , dfcon[3], width= bar_width, align = 'edge') ax.plot(kind='bar') ax.minorticks_on() ax.grid(which='major', linestyle='-', linewidth='0.5', color='green') ax.grid(which='minor', linestyle=':', linewidth='0.5', color='black') ax.set_ylabel('Time') descriptors = ('Tag', 'Target', 'Actual', 'Small #') ax_table = plt.table(cellText=test_data, rowLabels = descriptors, loc='center') ax_table.auto_set_font_size(False) ax_table.set_fontsize(12) fig.canvas.draw() fig.canvas.flush_events() fig.show() plt.pause(10)
我尝试过多种方法维持表格尺寸与位置,包括在循环内重新声明DataFrame、调用ax_table.clear()等,但未能解决表格未刷新反而重写并缩小的问题,部分操作还引发了错误。
修复后的可行代码
经调整后,核心修复点包括:
- 每次循环清除表格区域的坐标轴内容
- 重新关闭表格区域的坐标轴,避免多余元素干扰
- 使用
bbox参数控制表格的尺寸范围,确保表格占满分配的空间 - 将表格添加到预先创建的
ax_table坐标轴,而非覆盖坐标轴对象
import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np import pandas as pd # 顶部显示较大柱状图,下方显示较小数据表格 fig, (ax, ax_table) = plt.subplots(nrows = 2, gridspec_kw = dict(height_ratios = [7,1])) mng = plt.get_current_fig_manager() mng.full_screen_toggle() # 切换至全屏显示 while(True): test_data = [["A","B","A","B","A","B","A","B","A","B"], [1,2,3,4,5,6,7,8,9,10], [100,200,300,400,500,600,700,800,900,1000], [0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]] dfcon = pd.DataFrame(test_data) dfcon = dfcon.transpose() print('dfcon = ') print(dfcon) ax.cla() # 清除当前坐标轴(柱状图区域) ax_table.cla() # 清除当前坐标轴(表格区域) ticks = np.arange(len(dfcon)) bar_width = 0.4 ax.set_xticks(ticks) ax.margins(x=0.01) # 按元素数量分配两侧边距,使柱状图与表格对齐 b1 = ax.bar(ticks , dfcon[1], width= -(bar_width), align = 'edge') # 负宽度使柱状图对齐刻度左侧 b2 = ax.bar(ticks , dfcon[3], width= bar_width, align = 'edge') ax.plot(kind='bar') ax.minorticks_on() ax.grid(which='major', linestyle='-', linewidth='0.5', color='green') ax.grid(which='minor', linestyle=':', linewidth='0.5', color='black') ax.set_ylabel('Time') descriptors = ('Tag', 'Target', 'Actual', 'Small #') ax_table.cla() ax_table.axis('off') # 移除多余的图表坐标轴 # 创建新表格并添加至坐标轴 tb = plt.table(cellText=test_data, rowLabels = descriptors, bbox = [0,0,1,1.5], loc='center') # 添加bbox确保表格尺寸正确 tb.auto_set_font_size(False) tb.set_fontsize(12) ax_table.add_table(tb) fig.canvas.draw() fig.canvas.flush_events() fig.show() plt.pause(10)
内容的提问来源于stack exchange,提问作者Professor Barney
相关产品推荐
相关产品推荐

