如何在图下方居中 matplotlib 滑块并重新标记滑块标签?
Posted
技术标签:
【中文标题】如何在图下方居中 matplotlib 滑块并重新标记滑块标签?【英文标题】:How to center matplotlib slider below figure and relabel slider label? 【发布时间】:2022-01-23 19:08:00 【问题描述】:我创建了一个使用滑块播放动画的函数。每帧由条形图上方的热图(带颜色条)组成。该函数的参数由用于热图轴标签和条形图水平轴标签的文本标签列表、矩阵列表和用于条形图的列表列表组成。此外,还有一个时间窗口值,标记为win_value
,因此第 0 帧对应时间 0,第 1 帧对应win_value
,第 2 帧对应 2*win_value
,依此类推。
函数代码如下:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.widgets import Slider
def heatmap_barplot_animation(labels,M_list,bar_list,win_value):
num_times=len(M_list)
fig, ax = plt.subplots(2)
plt.subplots_adjust(left=None, bottom=.2, right=None, top=.9, wspace=.2, hspace=.2)
ax_time=fig.add_axes([0.25, 0.1, 0.65, 0.03])
s_time = Slider(ax_time, 'Time', 0, num_times, valinit=0,valstep=1)
def update_graph(val):
i= s_time.val
ax[0].cla()
heatmap=ax[0].imshow(M_list[i-1*1],vmin=0, vmax=1, cmap='coolwarm', aspect='auto')
ax[0].set_xticks(range(len(labels)))
ax[0].set_xticklabels(labels,fontsize=10,)
a.x[0].set_yticks(range(len(labels)))
ax[0].set_yticklabels(labels,fontsize=10)
ax0_divider = make_axes_locatable(ax[0])
cax0 = ax0_divider.append_axes('right', size='7%', pad='2%')
cb = fig.colorbar(heatmap, cax=cax0, orientation='vertical')
ax[1].cla()
ax[1].bar(labels,bar_list[i-1])
ax[1].set_ylim(0, 1)
plt.show()
s_time.on_changed(update_graph)
s_time.set_val(0)
一个包含 7 个标签、10 个帧和 0.25 秒窗口值的示例:
import random
labels=['a','b','c','d','e','f','g','h']
M_list=[np.random.rand(7,7) for i in range(10)]
bar_list=[[random.uniform(0,1) for i in range(Nc)] for t in range(Nt)]
win_value=.25
heatmap_barplot_animation(labels,M_list,bar_list,win_value)
动画的第三帧是这样的:
我似乎无法弄清楚执行以下操作需要哪些修改:
-
使条形图下方的滑块居中。
更改条形图滑块,使其不再显示索引(上面的 3),而是显示相应的时间值,在本例中为 0.75 秒。
【问题讨论】:
【参考方案1】:对于您的第一个问题,将滑块置于子图上的一种方法是简单地使用 plt.subplots_adjust
调整子图的位置以匹配滑块的轴。在您的代码中,滑块的轴定义为:ax_time=fig.add_axes([0.25, 0.1, 0.65, 0.03])
,因此您可能希望使用plt.subplots_adjust(left=0.25, bottom=.2, right=None, top=.9, wspace=.2, hspace=.2)
调整子图。您可以使用滑块的轴和子图的轴来获得所需的结果(请参阅下面的示例,滑块以子图为中心)。
针对您的第二个问题,要重新标记滑块中的值,您只需将标签的 valmax
和 valstep
值更改为 valmax=num_times*win_value
和 valstep=win_value
。要索引您的 M_list
和 bar_list
数组,您需要将 i
声明为 i=int(s_time.val/win_value)
。
更多细节请看您在实现上述修改后提供的代码:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.widgets import Slider
import random
def heatmap_barplot_animation(labels,M_list,bar_list,win_value):
num_times=len(M_list)
fig, ax = plt.subplots(2)
plt.subplots_adjust(left=0.25, bottom=.2, right=None, top=.9, wspace=.2, hspace=.2)
ax_time=fig.add_axes([0.25, 0.1, 0.65, 0.03])
s_time = Slider(ax_time, 'Time',valinit=0,valmin=0,valmax=num_times*win_value,valstep=win_value)
def update_graph(val):
i=int(s_time.val/win_value)
ax[0].cla()
heatmap=ax[0].imshow(M_list[i-1*1],vmin=0, vmax=1, cmap='coolwarm', aspect='auto')
ax[0].set_xticks(range(len(labels)))
ax[0].set_xticklabels(labels,fontsize=10,)
ax[0].set_yticks(range(len(labels)))
ax[0].set_yticklabels(labels,fontsize=10)
ax0_divider = make_axes_locatable(ax[0])
cax0 = ax0_divider.append_axes('right', size='7%', pad='2%')
cb = fig.colorbar(heatmap, cax=cax0, orientation='vertical')
ax[1].cla()
ax[1].bar(labels,bar_list[i-1])
ax[1].set_ylim(0, 1)
plt.show()
s_time.on_changed(update_graph)
s_time.set_val(0)
labels=['a','b','c','d','e','f','g','h']
Nc=8
Nt=10
M_list=[np.random.rand(Nc,Nc) for i in range(Nt)]
bar_list=[[random.uniform(0,1) for i in range(Nc)] for t in range(Nt)]
win_value=.25
heatmap_barplot_animation(labels,M_list,bar_list,win_value)
输出给出(在第 3 帧):
【讨论】:
这太棒了!谢谢。以上是关于如何在图下方居中 matplotlib 滑块并重新标记滑块标签?的主要内容,如果未能解决你的问题,请参考以下文章