使用matplotlib滑块控件更改图像的clim

8 投票
2 回答
11386 浏览
提问于 2025-04-16 15:26

我对Python几乎没有经验,但我正在尝试创建一个简单的脚本,加载一张图片,并使用滑块控件来调整颜色条的最小值和最大值,然后相应地重新绘制图像数据。

我在尝试跟着这个例子:http://matplotlib.sourceforge.net/examples/widgets/slider_demo.html。我试着把绘图命令改成imshow,并用滑块的值来设置我图像的clim(颜色限制)。但是我在下面代码的第12行调用'im1,=ax.imshow'时,收到了以下错误信息:

'AxesImage'对象不可迭代

我不太明白这个调用是干什么的,但显然它不能和imshow()一起使用。如果我去掉那个调用中的逗号,就不会出现错误了,但当我调整滑块时,图像不会更新。有没有人能提供一个替代方案,或者解释一下为什么这样不行?任何帮助都非常感谢,谢谢。

我的代码如下:

from pylab import *
from matplotlib.widgets import Slider, Button, RadioButtons
import matplotlib.pyplot as plt
import numpy as np

close('all')

ax = subplot(111)
subplots_adjust(left=0.25, bottom=0.25)
min0 = 0
max0 = 25000

im=np.loadtxt('im.txt')
im1,=ax.imshow(im)
colorbar()

axcolor = 'lightgoldenrodyellow'
axmin = axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor)
axmax  = axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)

smin = Slider(axmin, 'Min', 0, 30000, valinit=min0)
smax = Slider(axmax, 'Max', 0, 30000, valinit=max0)

def update(val):
    im1.set_clim=(smin.val,smax.val)
    draw()
smin.on_changed(update)
smax.on_changed(update)

show()

2 个回答

1

根据文档,imshow 会返回一个 `matplotlib.image.AxesImage` 对象。当你加上那个逗号时,Python 会认为这个函数的返回值是某种可以迭代的东西(通常是元组,但不一定)。因为 Python 允许你写这样的代码:

a = my_function() # a = (c, d)
a, b = my_function() # a = c, b = d

但是

a, = my_function() # you should get an error

我不太确定 Python 在 im1 里放了什么,除非我去检查(不过从你的问题来看,我觉得写 im1,=... 是有效的,而 im1=... 就不行),但我怀疑你可能因为某种原因没有成功绘制图像。update 真的有被调用吗?如果有的话,试试用 im1.draw() 来看看。

11

主要是你有很多语法上的问题。

比如,你试图解包一个单一的值(im1,=ax.imshow(im)),这就导致了你在问题中提到的TypeError错误(这是正常的)。还有,你把一个函数赋值给了一个变量,但其实你是想调用它:(im1.set_clim=(smin.val,smax.val)).

另外,我把你示例中的from pylab import *去掉了。这在交互式使用时可以,但请千万不要在实际代码中使用。这样会让人很难判断你调用的函数来自哪里(而且pylab的命名空间特别大,设计上就是这样的。它应该只用于交互式使用或快速的一次性脚本。)

这里有一个使用随机数据的工作示例:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.widgets import Slider, Button, RadioButtons

fig = plt.figure()
ax = fig.add_subplot(111)
fig.subplots_adjust(left=0.25, bottom=0.25)
min0 = 0
max0 = 25000

im = max0 * np.random.random((10,10))
im1 = ax.imshow(im)
fig.colorbar(im1)

axcolor = 'lightgoldenrodyellow'
axmin = fig.add_axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor)
axmax  = fig.add_axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)

smin = Slider(axmin, 'Min', 0, 30000, valinit=min0)
smax = Slider(axmax, 'Max', 0, 30000, valinit=max0)

def update(val):
    im1.set_clim([smin.val,smax.val])
    fig.canvas.draw()
smin.on_changed(update)
smax.on_changed(update)

plt.show()

撰写回答