axvspan/axvline trashes view limits

Hey all,

I've come across quite a problem while using pylab in a recent project.
It seems that the second time I call axvspan or axvline, the view limits
are reset (seemingly arbitrarily). I have attached a code sample
(derived from my project) to demonstrate this issue. The code sample
opens a figure with a single line and vline, adding another set with
every key press. You will see that when the figure is initially plotted,
the view limits are correct for the dataset, however as the second
line/vline is plotted, the limits are stretched. It seems that this must
be a bug in matplotlib. Any help or input anyone could offer would be
greatly appreciated. Thanks,

- Ben

test.py (1.3 KB)

Ben Gamari (FOSS) wrote:

Hey all,

I've come across quite a problem while using pylab in a recent project.
It seems that the second time I call axvspan or axvline, the view limits
are reset (seemingly arbitrarily). I have attached a code sample
(derived from my project) to demonstrate this issue. The code sample
opens a figure with a single line and vline, adding another set with
every key press. You will see that when the figure is initially plotted,
the view limits are correct for the dataset, however as the second
line/vline is plotted, the limits are stretched. It seems that this must
be a bug in matplotlib. Any help or input anyone could offer would be
greatly appreciated. Thanks,

This bug is fixed now in svn for axvline and axhline. If you need a workaround for your current version of mpl, you could save the view limits before the axvline call and restore them after it.

I still need to check axvspan and axhspan; they probably need a similar fix.

Eric

Eric Firing wrote:

This bug is fixed now in svn for axvline and axhline. If you need a
workaround for your current version of mpl, you could save the view
limits before the axvline call and restore them after it.

I still need to check axvspan and axhspan; they probably need a
similar fix.

Eric

Thanks a ton!

While I though this would be fairly
easy, I’ve yet to find a decent solution. I’m interested in using the
RangeSelector or standard zoom feature along with an autoscaling
function. In the example below there are two gaussian profiles created
in a matrix. I would like to have the behavior in which when I zoom in
that the Z scale is reordered to account for the new range of data. Is
my only solution to take the limits returned by a RangeSelector event
and extract a sub-matix from the original data and replot each time I
zoom in or out or is there a more elegant solution? Is there a way to also extend such functionality to contour, pcolor, etc.?

Cheers,

Brian

######paste in ipython###########################################

from numpy import *

from matplotlib.widgets import RectangleSelector

import pylab as P

def gaussian(height, center_x, center_y, width_x, width_y):

"""Returns a gaussian function with the given parameters"""

width_x = float(width_x)

width_y = float(width_y)

return lambda x,y: height*exp(-(((center_x-x)/width_x)**2+((center_y-y)/width_y)**2)/2)

def line_select_callback(event1, event2):

'event1 and event2 are the press and release events'

x1, y1 = event1.xdata, event1.ydata

x2, y2 = event2.xdata, event2.ydata

print "(%3.2f, %3.2f) --> (%3.2f, %3.2f)"%(x1,y1,x2,y2)

print " The button you used were: ",event1.button, event2.button

cla()

Create the gaussian data

Xin, Yin = mgrid[0:201, 0:201]

Xin2, Yin2 = mgrid[0:201, 0:201]

data = gaussian(20, 100, 100, 20, 40)(Xin, Yin) + random.random(Xin.shape)

data2 = gaussian(10, 10, 10, 2, 4)(Xin2, Yin2) + random.random(Xin.shape)

P.imshow(data+data2, cmap=cm.jet)

current_ax = gca()

LS = RectangleSelector(current_ax, line_select_callback, drawtype=‘box’,useblit=True,\

                   minspanx=5,minspany=5,spancoords='pixels')

P.show()