python - matplotlib.animation.FuncAnimation() 在每次刷新时向 seaborn.heatmap() 添加不需要的颜色条
问题描述
我正在尝试设置一个正在运行的seaborn.heatmap()
s 仪表板,它将使用matplotlib.animation.FuncAnimation()
. 这是一个好的 - 尽管大部分是空的 - 视觉应该看起来像
不幸的是,每次FuncAnimation()
触发时,图右侧都会添加更多列。
import datetime
from pyodbc import connect
from pandas import DataFrame
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
#settings up here
first_cycle = True
...
#create figure with subplots
fig,_ = plt.subplots(nrow,ncol)
fig.suptitle("Animated Heatmap(s)",fontsize=16)
#set subplot spacing
plt.subplots_adjust(left=0.05, bottom=0.02, right=1.00, top=0.96, hspace=0.35, wspace=0.08)
#maximize screen
plt.get_current_fig_manager().window.state('zoomed') #method works for Tk backend (default)
def load_figure(i, first_cycle):
#subplot iterator
for ax in fig.axes:
plt.sca(ax) #sets current axes
plt.xticks(rotation=30)
#get data from SQL Server
cursor = connect('DRIVER={ODBC Driver 17 for SQL Server}; \
SERVER=' + server + '; \
DATABASE=' + database + '; \
Trusted_Connection=yes;').cursor()
cursor.execute("SELECT end_of_shift, item, value FROM SecretTableName " +
"WHERE end_of_shift BETWEEN '" + query_start_time + "' AND CURRENT_TIMESTAMP")
data_CT_DBout = cursor.fetchall()
#create organized dataframes
data_CT_ts = [nameShift( roundTime(item[0]) ) for item in data_CT_DBout]
data_CT_item = [item[1] for item in data_CT_DBout]
data_CT_val = [item[2] for item in data_CT_DBout]
data_CT = DataFrame.from_dict({'Timestamp': data_CT_ts, 'CT': data_CT_item, 'Value': data_CT_val})
#reshape data
data_CT = data_CT.pivot(index = 'CT', columns = 'Timestamp', values = 'Value')
data_CT.drop(drop_index_CT, inplace=True)
data_CT.rename(index=rename_index_CT, inplace=True)
#render as heatmap
if first_cycle:
graph_CT = sns.heatmap(data_SH01, annot=True, linewidths=0.5, vmax=14, vmin=8, ax = fig.axes[0], cmap=cmap, xticklabels=True, yticklabels=True)
else:
graph_SH01 = sns.heatmap(data_SH01, annot=True, linewidths=0.5, vmax=14, vmin=8, ax = fig.axes[0], cmap=cmap, xticklabels=True, yticklabels=True, cbar = False)
loop_animation = FuncAnimation(fig, load_figure, interval = refresh_setting * 1000, fargs=(first_cycle,))
plt.show()
如果我添加更改#subplot iterator
为:
#subplot iterator
for ax in fig.axes:
ax.clear()
plt.sca(ax) #sets current axes
plt.xticks(rotation=30)
我也尝试ax.remove()
在 中使用#subplot iterator
,但它没有达到我的预期,我无法重新创建结果。
我正在使用fig,_ = plt.subplots()
,因为最终目标是让 5 个这些热图垂直堆叠,但即使是单个图表,我也遇到了同样的问题。我能够使用fig,_ = plt.subplots()
类似项目的动画散点图实现,但我可以通过更改它来解决动画问题。
任何想法或解决方案表示赞赏。
解决方案
上面的代码没有正确利用该first_cycle
变量。在其中,我尝试在函数和循环之外定义变量,然后将当前值传递给要运行的函数。经过进一步测试,即使包含在功能中print(first_cycle)
也不会显示。False
first_cycle = False
为了使它工作,代码应该重写如下:
first_cycle = True
...
def load_figure(i): #removed first_cycle argument
global first_cycle #added - be sure to use global variable
...
#render as heatmap
if first_cycle:
graph_CT = sns.heatmap(data_SH01, ... )
first_cycle = False #be sure to turn off first_cycle
else:
graph_SH01 = sns.heatmap(data_SH01, ... , cbar = False)
loop_animation = FuncAnimation(fig, load_figure, interval = refresh_setting * 1000)
#removed fargs argument
plt.show()
推荐阅读
- python - 使用 django 表单值更新表单输入
- python-3.x - 使用 CSV 文件中的名称列表遍历 API
- automated-tests - 赛普拉斯报告元素尺寸错误
- acumatica - Acumatica。如何根据给定日期创建参数
- laravel - Laravel 中可重用和独立的模块?
- react-native - 以平滑的方式更改 TextInput 的 fontSize
- ansible - Ansible 来自 /etc/ansible/hosts 的五个随机主机
- pandas - groupby pandas dataframe,取最新日期和最早日期的值之间的差异
- nginx - 404 时重定向到另一个站点
- kentico - 带有自定义查询的 Kentico 中继器