8

I have virtually no experience with python, but I am trying to create a simple script which loads an image and uses the slider widget to adjust the minimum and maximum of the colorbar, and redraws the image data accordingly.

I am trying to follow this example: http://matplotlib.sourceforge.net/examples/widgets/slider_demo.html. I have tried to just change the plot command to imshow, and to use the slider values to set the clim of my image. However I get the following error message, from the call 'im1,=ax.imshow' (on line 12 in the code below):

'AxesImage' object is not iterable

I don't understand what this call does, but apparently it can not be used with imshow(). If I remove the comma in that call, I get no errors, but the image does not update when the sliders are changed. Does anyone have an alternative solution, or an explanation of why this does not work? Any help would be appreciated, thank you.

My code is as follows:

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 Answers 2

11

Mostly, you just had lots and lots of syntax problems.

For example, you were trying to unpack a single value (im1,=ax.imshow(im)) giving you the TypeError you mentioned in your question (as it should). You also set a function to a value when you meant to call it: (im1.set_clim=(smin.val,smax.val)).

Also, I removed the from pylab import * from your example. This is fine for interactive use, but please, please, please don't use it for actual code. It makes it very difficult to tell where the functions you're calling are coming from (and the pylab namespace, in particular, is huge by design. It should only be used for interactive use or quick one-use scripts.)

Here's a working example (using random data):

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()
Sign up to request clarification or add additional context in comments.

2 Comments

If someone arrives here because 'imshow()' doesn't update inside the update function and you're using numpy to fill 'imshow', you should use int() in the variables that comes from the Slider, ie, imshow( [int(var_from_slider_a), int(var_from_slider_b)] )
Further to @AlejoBernardin 's comment, you may also be required to call im1.draw() after im1.set_clim(...), im1.set_data(...) or similar.
1

According to the documentation, imshow returns a `matplotlib.image.AxesImage' object. When you put in that comma, Python assumes that the return type of the function is going to be something iterable (usually a tuple when you would be using this construction, but not necessarily) because Python lets you write code like this:

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

but

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

I'm not entirely sure what Python is putting in im1 without checking (but from your question I get the impression that writing im1,=... works while im1=... doesn't), but I suspect you are failing to draw the image for some reason. Does update actually get called? If it does, maybe try im1.draw() instead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.