如何使用PyPlot绘制带有2个滑块的4D数组?

时间:2017-09-20 16:55:28

标签: python numpy matplotlib

我有一个4D数据集(对于那些关心,它是一个天文位置 - 位置 - 温度 - 不透明度图像)在一个numpy数组中,我需要以交互方式绘图。虽然有程序可以做到这一点,但是没有一个程序可以处理我的数据所处的异常形式(但我可以担心,这不是问题的一部分)。

我知道如何用一个Slider进行绘图,但实际上我需要用2 Sliders绘制图像,每个温度和不透明度一个。

我的三维数组代码的MWE如下:

import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
import numpy as np

array = np.random.rand(300,300,10)

axis = 2
s = [slice(0, 1) if i == axis else slice(None) for i in xrange(array.ndim)]
im = array[s].squeeze()

fig = plt.figure()
ax = plt.subplot(111)
l = ax.imshow(im, origin = 'lower')
axcolor = 'lightgoldenrodyellow'
ax = fig.add_axes([0.2, 0.95, 0.65, 0.03], axisbg=axcolor)

slider = Slider(ax, 'Temperature', 0, array.shape[axis] - 1,
                    valinit=0, valfmt='%i')

def update(val):
    ind = int(slider.val)
    s = [slice(ind, ind + 1) if i == axis else slice(None)
             for i in xrange(array.ndim)]
    im = array[s].squeeze()
    l.set_data(im)
    fig.canvas.draw()

slider.on_changed(update)

plt.show()

用2个滑块做任何方法吗?

编辑:我遇到的问题是我不知道如何扩展到2个滑块。特别是如何适应这条线

s = [slice(0, 1) if i == axis else slice(None) for i in xrange(array.ndim)]

以及当我从update转到np.random.rand(300,300,10)时如何修改np.random.rand(300,300,10,10)功能。我想我需要声明一个T_axis = 2B_axis = 3,而不仅仅是axis = 2,但除此之外,我更倾向于如何修改它。

1 个答案:

答案 0 :(得分:1)

当我解释数据结构时,你有一个形状(300,300,n,m)的数组,其中n是温度数,m是不透明数。因此,显示i温度和j不透明度的图像为array[:,:,i,j]

您现在需要两个不同的傻瓜,其中一个确定i的值,另一个确定j的值。

import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
import numpy as np

array = np.random.rand(300,300,10,9)
# assuming you have for each i=Temperature index and j =Opacity index
# an image array(:,:,i,j)

fig, ax = plt.subplots()
l = ax.imshow(array[:,:,0,0], origin = 'lower')

axT = fig.add_axes([0.2, 0.95, 0.65, 0.03])
axO = fig.add_axes([0.2, 0.90, 0.65, 0.03])

sliderT = Slider(axT, 'Temperature', 0, array.shape[2]-1, valinit=0, valfmt='%i')
sliderO = Slider(axO, 'Opacity', 0, array.shape[3]-1, valinit=0, valfmt='%i')

def update(val):
    i = int(sliderT.val)
    j = int(sliderO.val)
    im = array[:,:,i,j]
    l.set_data(im)
    fig.canvas.draw_idle()

sliderT.on_changed(update)
sliderO.on_changed(update)

plt.show()