irr*_*rom 5 python plot matplotlib
我正在生成一组3D数据的2D热图.我希望能够有一个机制来交互式地浏览每个窗格.下面是一个简单的示例代码,我希望能够通过滑动条(或其他方法)以交互方式查看两个窗格(即z = [0,1]).matplotlib可以实现这一点,还是生成图像文件后我需要做后期处理?
import numpy as np
from matplotlib import pyplot as plt
data = np.random.randint(10, size=(5, 5, 2))
data_slice = np.zeros((5,5))
for i in range(0, 5):
for j in range(0, 5):
data_slice[i][j] = data[i][j][0]
plt.imshow(data_slice, cmap='hot', interpolation='nearest')
plt.show()
Run Code Online (Sandbox Code Playgroud)
编辑:我希望能够以交互方式执行此操作,并且似乎可能的重复尝试自动执行此操作.
Imp*_*est 11
解决方案确实可以使用滑块,就像@hashmuke的优秀答案一样.在他的回答中,他提到 "滑块是连续的,而层索引是一个离散的整数[...]"
这让我想到了一个没有这个限制的解决方案,并且具有
更像页面的外观和感觉.
结果是PageSlider.Slider对它进行子类化 会使用滑块功能,但会以整数步开始显示滑块1.它将页面的数量numpages作为init参数,但除了Slider从外部看到的那样起作用.此外,它还提供后退和前进按钮.
类似于@hashmuke的一个例子,在类下面给出.
import matplotlib.widgets
import matplotlib.patches
import mpl_toolkits.axes_grid1
class PageSlider(matplotlib.widgets.Slider):
def __init__(self, ax, label, numpages = 10, valinit=0, valfmt='%1d',
closedmin=True, closedmax=True,
dragging=True, **kwargs):
self.facecolor=kwargs.get('facecolor',"w")
self.activecolor = kwargs.pop('activecolor',"b")
self.fontsize = kwargs.pop('fontsize', 10)
self.numpages = numpages
super(PageSlider, self).__init__(ax, label, 0, numpages,
valinit=valinit, valfmt=valfmt, **kwargs)
self.poly.set_visible(False)
self.vline.set_visible(False)
self.pageRects = []
for i in range(numpages):
facecolor = self.activecolor if i==valinit else self.facecolor
r = matplotlib.patches.Rectangle((float(i)/numpages, 0), 1./numpages, 1,
transform=ax.transAxes, facecolor=facecolor)
ax.add_artist(r)
self.pageRects.append(r)
ax.text(float(i)/numpages+0.5/numpages, 0.5, str(i+1),
ha="center", va="center", transform=ax.transAxes,
fontsize=self.fontsize)
self.valtext.set_visible(False)
divider = mpl_toolkits.axes_grid1.make_axes_locatable(ax)
bax = divider.append_axes("right", size="5%", pad=0.05)
fax = divider.append_axes("right", size="5%", pad=0.05)
self.button_back = matplotlib.widgets.Button(bax, label=ur'$\u25C0$',
color=self.facecolor, hovercolor=self.activecolor)
self.button_forward = matplotlib.widgets.Button(fax, label=ur'$\u25B6$',
color=self.facecolor, hovercolor=self.activecolor)
self.button_back.label.set_fontsize(self.fontsize)
self.button_forward.label.set_fontsize(self.fontsize)
self.button_back.on_clicked(self.backward)
self.button_forward.on_clicked(self.forward)
def _update(self, event):
super(PageSlider, self)._update(event)
i = int(self.val)
if i >=self.valmax:
return
self._colorize(i)
def _colorize(self, i):
for j in range(self.numpages):
self.pageRects[j].set_facecolor(self.facecolor)
self.pageRects[i].set_facecolor(self.activecolor)
def forward(self, event):
current_i = int(self.val)
i = current_i+1
if (i < self.valmin) or (i >= self.valmax):
return
self.set_val(i)
self._colorize(i)
def backward(self, event):
current_i = int(self.val)
i = current_i-1
if (i < self.valmin) or (i >= self.valmax):
return
self.set_val(i)
self._colorize(i)
if __name__ == "__main__":
import numpy as np
from matplotlib import pyplot as plt
num_pages = 23
data = np.random.rand(9, 9, num_pages)
fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.18)
im = ax.imshow(data[:, :, 0], cmap='viridis', interpolation='nearest')
ax_slider = fig.add_axes([0.1, 0.05, 0.8, 0.04])
slider = PageSlider(ax_slider, 'Page', num_pages, activecolor="orange")
def update(val):
i = int(slider.val)
im.set_data(data[:,:,i])
slider.on_changed(update)
plt.show()
Run Code Online (Sandbox Code Playgroud)
您可以按照安德鲁评论的建议为图层设置动画,也可以使用滑块手动浏览图层,如下所示:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.widgets import Slider
# generate a five layer data
data = np.random.randint(10, size=(5, 5, 5))
# current layer index start with the first layer
idx = 0
# figure axis setup
fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.15)
# display initial image
im_h = ax.imshow(data[:, :, idx], cmap='hot', interpolation='nearest')
# setup a slider axis and the Slider
ax_depth = plt.axes([0.23, 0.02, 0.56, 0.04])
slider_depth = Slider(ax_depth, 'depth', 0, data.shape[2]-1, valinit=idx)
# update the figure with a change on the slider
def update_depth(val):
idx = int(round(slider_depth.val))
im_h.set_data(data[:, :, idx])
slider_depth.on_changed(update_depth)
plt.show()
Run Code Online (Sandbox Code Playgroud)
滑块是继续而图层索引是离散整数,我希望不是问题.这是结果图,