From: <ef...@us...> - 2010-06-30 21:07:43
|
Revision: 8479 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8479&view=rev Author: efiring Date: 2010-06-30 21:07:36 +0000 (Wed, 30 Jun 2010) Log Message: ----------- set_xlim, set_ylim: turn off autoscaling; added autoscale method Modified Paths: -------------- trunk/matplotlib/boilerplate.py trunk/matplotlib/lib/matplotlib/axes.py trunk/matplotlib/lib/matplotlib/blocking_input.py trunk/matplotlib/lib/matplotlib/image.py trunk/matplotlib/lib/matplotlib/projections/polar.py trunk/matplotlib/lib/matplotlib/pylab.py trunk/matplotlib/lib/matplotlib/pyplot.py trunk/matplotlib/lib/matplotlib/tests/test_dates.py trunk/matplotlib/lib/matplotlib/widgets.py trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py Modified: trunk/matplotlib/boilerplate.py =================================================================== --- trunk/matplotlib/boilerplate.py 2010-06-30 16:31:23 UTC (rev 8478) +++ trunk/matplotlib/boilerplate.py 2010-06-30 21:07:36 UTC (rev 8479) @@ -109,6 +109,7 @@ 'locator_params', 'tick_params', 'margins', + 'autoscale', ) cmappable = { Modified: trunk/matplotlib/lib/matplotlib/axes.py =================================================================== --- trunk/matplotlib/lib/matplotlib/axes.py 2010-06-30 16:31:23 UTC (rev 8478) +++ trunk/matplotlib/lib/matplotlib/axes.py 2010-06-30 21:07:36 UTC (rev 8479) @@ -1715,7 +1715,46 @@ """ return self._rasterization_zorder + def autoscale(self, enable=True, axis='both', tight=None): + """ + Convenience method for simple axis view autoscaling. + It turns autoscaling on or off, and then, + if autoscaling for either axis is on, it performs + the autoscaling on the specified axis or axes. + *enable*: [True | False | None] + True (default) turns autoscaling on, False turns it off. + None leaves the autoscaling state unchanged. + + *axis*: ['x' | 'y' | 'both'] + which axis to operate on; default is 'both' + + *tight*: [True | False | None] + If True, set view limits to data limits; + if False, let the locator and margins expand the view limits; + if None, use tight scaling if the only artist is an image, + otherwise treat *tight* as False. + The *tight* setting is retained for future autoscaling + until it is explicitly changed. + + + Returns None. + """ + if enable is None: + scalex = True + scaley = True + else: + scalex = False + scaley = False + if axis in ['x', 'both']: + self._autoscaleXon = bool(enable) + scalex = self._autoscaleXon + if axis in ['y', 'both']: + self._autoscaleYon = bool(enable) + scaley = self._autoscaleYon + self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley) + + def autoscale_view(self, tight=None, scalex=True, scaley=True): """ autoscale the view limits using the data limits. You can @@ -2209,7 +2248,7 @@ def invert_xaxis(self): "Invert the x-axis." left, right = self.get_xlim() - self.set_xlim(right, left) + self.viewLim.intervalx = (right, left) def xaxis_inverted(self): 'Returns True if the x-axis is inverted.' @@ -2233,6 +2272,7 @@ """ Set the lower and upper numerical bounds of the x-axis. This method will honor axes inversion regardless of parameter order. + It will not change the _autoscaleXon attribute. """ if upper is None and iterable(lower): lower,upper = lower @@ -2244,14 +2284,14 @@ if self.xaxis_inverted(): if lower < upper: - self.set_xlim(upper, lower) + self.set_xlim(upper, lower, auto=None) else: - self.set_xlim(lower, upper) + self.set_xlim(lower, upper, auto=None) else: if lower < upper: - self.set_xlim(lower, upper) + self.set_xlim(lower, upper, auto=None) else: - self.set_xlim(upper, lower) + self.set_xlim(upper, lower, auto=None) def get_xlim(self): """ @@ -2259,32 +2299,45 @@ """ return tuple(self.viewLim.intervalx) - def set_xlim(self, xmin=None, xmax=None, emit=True, **kwargs): + def set_xlim(self, xmin=None, xmax=None, emit=True, auto=False): """ call signature:: - set_xlim(self, *args, **kwargs) + set_xlim(self, *args, **kwargs): - Set the limits for the xaxis + Set the data limits for the xaxis - Returns the current xlimits as a length 2 tuple: [*xmin*, *xmax*] - Examples:: - set_xlim((valmin, valmax)) - set_xlim(valmin, valmax) - set_xlim(xmin=1) # xmax unchanged - set_xlim(xmax=1) # xmin unchanged + set_xlim((left, right)) + set_xlim(left, right) + set_xlim(xmin=1) # right unchanged + set_xlim(xmax=1) # left unchanged Keyword arguments: *xmin*: scalar - the min of the ylim + the left xlim *xmax*: scalar - the max of the ylim + the right xlim *emit*: [ True | False ] notify observers of lim change + *auto*: [ True | False | None ] + turn *x* autoscaling on (True), off (False; default), + or leave unchanged (None) + Note: the kwarg terminology may be confusing. The first value, + *xmin*, is the left, and the second, *xmax*, is the right. + For example, suppose *x* is years before present. + Then one might use:: + + set_ylim(5000, 0) + + so 5000 years ago is on the left of the plot and the + present is on the right. + + Returns the current xlimits as a length 2 tuple + ACCEPTS: len(2) sequence of floats """ if xmax is None and iterable(xmin): @@ -2307,6 +2360,8 @@ xmin, xmax = self.xaxis.limit_range_for_scale(xmin, xmax) self.viewLim.intervalx = (xmin, xmax) + if auto is not None: + self._autoscaleXon = bool(auto) if emit: self.callbacks.process('xlim_changed', self) @@ -2391,25 +2446,26 @@ def invert_yaxis(self): "Invert the y-axis." - left, right = self.get_ylim() - self.set_ylim(right, left) + bottom, top = self.get_ylim() + self.viewLim.intervaly = (top, bottom) def yaxis_inverted(self): 'Returns True if the y-axis is inverted.' - left, right = self.get_ylim() - return right < left + bottom, top = self.get_ylim() + return top < bottom def get_ybound(self): "Return y-axis numerical bounds in the form of lowerBound < upperBound" - left, right = self.get_ylim() - if left < right: - return left, right + bottom, top = self.get_ylim() + if bottom < top: + return bottom, top else: - return right, left + return top, bottom def set_ybound(self, lower=None, upper=None): """Set the lower and upper numerical bounds of the y-axis. This method will honor axes inversion regardless of parameter order. + It will not change the _autoscaleYon attribute. """ if upper is None and iterable(lower): lower,upper = lower @@ -2421,14 +2477,14 @@ if self.yaxis_inverted(): if lower < upper: - self.set_ylim(upper, lower) + self.set_ylim(upper, lower, auto=None) else: - self.set_ylim(lower, upper) + self.set_ylim(lower, upper, auto=None) else: if lower < upper: - self.set_ylim(lower, upper) + self.set_ylim(lower, upper, auto=None) else: - self.set_ylim(upper, lower) + self.set_ylim(upper, lower, auto=None) def get_ylim(self): """ @@ -2436,28 +2492,43 @@ """ return tuple(self.viewLim.intervaly) - def set_ylim(self, ymin=None, ymax=None, emit=True, **kwargs): + def set_ylim(self, ymin=None, ymax=None, emit=True, auto=False): """ call signature:: set_ylim(self, *args, **kwargs): - Set the limits for the yaxis; v = [ymin, ymax]:: + Set the data limits for the yaxis - set_ylim((valmin, valmax)) - set_ylim(valmin, valmax) - set_ylim(ymin=1) # ymax unchanged - set_ylim(ymax=1) # ymin unchanged + Examples:: + set_ylim((bottom, top)) + set_ylim(bottom, top) + set_ylim(ymin=1) # top unchanged + set_ylim(ymax=1) # bottom unchanged + Keyword arguments: *ymin*: scalar - the min of the ylim + the bottom ylim *ymax*: scalar - the max of the ylim + the top ylim *emit*: [ True | False ] notify observers of lim change + *auto*: [ True | False | None ] + turn *y* autoscaling on (True), off (False; default), + or leave unchanged (None) + Note: the kwarg terminology may be confusing. The first value, + *ymin*, is the bottom, and the second, *ymax*, is the top. + For example, suppose *y* is depth in the ocean. + Then one might use:: + + set_ylim(5000, 0) + + so 5000 m depth is at the bottom of the plot and the + surface, 0 m, is at the top. + Returns the current ylimits as a length 2 tuple ACCEPTS: len(2) sequence of floats @@ -2480,7 +2551,10 @@ ymin, ymax = mtransforms.nonsingular(ymin, ymax, increasing=False) ymin, ymax = self.yaxis.limit_range_for_scale(ymin, ymax) + self.viewLim.intervaly = (ymin, ymax) + if auto is not None: + self._autoscaleYon = bool(auto) if emit: self.callbacks.process('ylim_changed', self) @@ -6647,14 +6721,10 @@ im.autoscale_None() im.set_url(url) - xmin, xmax, ymin, ymax = im.get_extent() + # update ax.dataLim, and, if autoscaling, set viewLim + # to tightly fit the image, regardless of dataLim. + im.set_extent(im.get_extent()) - corners = (xmin, ymin), (xmax, ymax) - self.update_datalim(corners) - if self._autoscaleXon: - self.set_xlim((xmin, xmax)) - if self._autoscaleYon: - self.set_ylim((ymin, ymax)) self.images.append(im) im._remove_method = lambda h: self.images.remove(h) Modified: trunk/matplotlib/lib/matplotlib/blocking_input.py =================================================================== --- trunk/matplotlib/lib/matplotlib/blocking_input.py 2010-06-30 16:31:23 UTC (rev 8478) +++ trunk/matplotlib/lib/matplotlib/blocking_input.py 2010-06-30 21:07:36 UTC (rev 8479) @@ -19,6 +19,7 @@ from matplotlib import path, verbose from matplotlib.cbook import is_sequence_of_strings +import matplotlib.lines as mlines class BlockingInput(object): """ @@ -222,18 +223,10 @@ # If desired plot up click if self.show_clicks: - - # make sure we don't mess with the axes zoom - xlim = event.inaxes.get_xlim() - ylim = event.inaxes.get_ylim() - - # plot the clicks - self.marks.extend( - event.inaxes.plot([event.xdata,], [event.ydata,], 'r+') ) - - # before we draw, make sure to reset the limits - event.inaxes.set_xlim(xlim) - event.inaxes.set_ylim(ylim) + line = mlines.Line2D([event.xdata], [event.ydata], + marker='+', color='r') + event.inaxes.add_line(line) + self.marks.append(line) self.fig.canvas.draw() @@ -247,16 +240,9 @@ if self.show_clicks: - # make sure we don't mess with the axes zoom - xlim = event.inaxes.get_xlim() - ylim = event.inaxes.get_ylim() - mark = self.marks.pop(index) mark.remove() - # before we draw, make sure to reset the limits - event.inaxes.set_xlim(xlim) - event.inaxes.set_ylim(ylim) self.fig.canvas.draw() # NOTE: I do NOT understand why the above 3 lines does not work # for the keyboard backspace event on windows XP wxAgg. @@ -275,20 +261,11 @@ def cleanup(self,event=None): # clean the figure if self.show_clicks: - if event: - # make sure we don't mess with the axes zoom - xlim = event.inaxes.get_xlim() - ylim = event.inaxes.get_ylim() for mark in self.marks: mark.remove() self.marks = [] - if event: - # before we draw, make sure to reset the limits - event.inaxes.set_xlim(xlim) - event.inaxes.set_ylim(ylim) - self.fig.canvas.draw() # Call base class to remove callbacks Modified: trunk/matplotlib/lib/matplotlib/image.py =================================================================== --- trunk/matplotlib/lib/matplotlib/image.py 2010-06-30 16:31:23 UTC (rev 8478) +++ trunk/matplotlib/lib/matplotlib/image.py 2010-06-30 21:07:36 UTC (rev 8479) @@ -605,6 +605,12 @@ def set_extent(self, extent): """ extent is data axes (left, right, bottom, top) for making image plots + + This updates ax.dataLim, and, if autoscaling, sets viewLim + to tightly fit the image, regardless of dataLim. Autoscaling + state is not changed, so following this with ax.autoscale_view + will redo the autoscaling in accord with dataLim. + """ self._extent = extent @@ -612,9 +618,9 @@ corners = (xmin, ymin), (xmax, ymax) self.axes.update_datalim(corners) if self.axes._autoscaleXon: - self.axes.set_xlim((xmin, xmax)) + self.axes.set_xlim((xmin, xmax), auto=None) if self.axes._autoscaleYon: - self.axes.set_ylim((ymin, ymax)) + self.axes.set_ylim((ymin, ymax), auto=None) def get_extent(self): 'get the image extent: left, right, bottom, top' Modified: trunk/matplotlib/lib/matplotlib/projections/polar.py =================================================================== --- trunk/matplotlib/lib/matplotlib/projections/polar.py 2010-06-30 16:31:23 UTC (rev 8478) +++ trunk/matplotlib/lib/matplotlib/projections/polar.py 2010-06-30 21:07:36 UTC (rev 8479) @@ -336,12 +336,13 @@ def get_rmin(self): return self.viewLim.ymin - def set_rlim(self, rmin=None, rmax=None): - self.viewLim.y0 = rmin - self.viewLim.y1 = rmax + def set_rlim(self, *args, **kwargs): + if 'rmin' in kwargs: + kwargs['ymin'] = kwargs.pop('rmin') + if 'rmax' in kwargs: + kwargs['ymax'] = kwargs.pop('rmax') + return self.set_ylim(*args, **kwargs) - set_ylim = set_rlim - def set_yscale(self, *args, **kwargs): Axes.set_yscale(self, *args, **kwargs) self.yaxis.set_major_locator( Modified: trunk/matplotlib/lib/matplotlib/pylab.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pylab.py 2010-06-30 16:31:23 UTC (rev 8478) +++ trunk/matplotlib/lib/matplotlib/pylab.py 2010-06-30 21:07:36 UTC (rev 8479) @@ -17,6 +17,7 @@ axhspan - draw a horizontal bar across axes axvspan - draw a vertical bar across axes axis - Set or return the current axis limits + autoscale - turn axis autoscaling on or off, and apply it bar - make a bar chart barh - a horizontal bar chart broken_barh - a set of horizontal bars with gaps Modified: trunk/matplotlib/lib/matplotlib/pyplot.py =================================================================== --- trunk/matplotlib/lib/matplotlib/pyplot.py 2010-06-30 16:31:23 UTC (rev 8478) +++ trunk/matplotlib/lib/matplotlib/pyplot.py 2010-06-30 21:07:36 UTC (rev 8479) @@ -2132,7 +2132,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @autogen_docstring(Axes.hexbin) -def hexbin(x, y, C=None, gridsize=100, bins=None, xscale='linear', yscale='linear', extent=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=1.0, linewidths=None, edgecolors='none', reduce_C_function=np.mean, mincnt=None, marginals=False, hold=None, **kwargs): +def hexbin(x, y, C=None, gridsize=100, bins=None, xscale='linear', yscale='linear', extent=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, edgecolors='none', reduce_C_function=np.mean, mincnt=None, marginals=False, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2186,7 +2186,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @autogen_docstring(Axes.imshow) -def imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=1.0, vmin=None, vmax=None, origin=None, extent=None, shape=None, filternorm=1, filterrad=4.0, imlim=None, resample=None, url=None, hold=None, **kwargs): +def imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None, vmin=None, vmax=None, origin=None, extent=None, shape=None, filternorm=1, filterrad=4.0, imlim=None, resample=None, url=None, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2366,7 +2366,7 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @autogen_docstring(Axes.scatter) -def scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, vmax=None, alpha=1.0, linewidths=None, faceted=True, verts=None, hold=None, **kwargs): +def scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, faceted=True, verts=None, hold=None, **kwargs): ax = gca() # allow callers to override the hold state by passing hold=True|False washold = ax.ishold() @@ -2608,8 +2608,8 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost @docstring.copy_dedent(Axes.grid) -def grid(b=None, **kwargs): - ret = gca().grid(b, **kwargs) +def grid(b=None, which='major', **kwargs): + ret = gca().grid(b, which, **kwargs) draw_if_interactive() return ret @@ -2679,6 +2679,14 @@ # This function was autogenerated by boilerplate.py. Do not edit as # changes will be lost +...@do...py_dedent(Axes.autoscale) +def autoscale(enable=True, axis='both', tight=None): + ret = gca().autoscale(enable, axis, tight) + draw_if_interactive() + return ret + +# This function was autogenerated by boilerplate.py. Do not edit as +# changes will be lost def autumn(): ''' set the default colormap to autumn and apply to current image if any. @@ -2902,4 +2910,3 @@ draw_if_interactive() - Modified: trunk/matplotlib/lib/matplotlib/tests/test_dates.py =================================================================== --- trunk/matplotlib/lib/matplotlib/tests/test_dates.py 2010-06-30 16:31:23 UTC (rev 8478) +++ trunk/matplotlib/lib/matplotlib/tests/test_dates.py 2010-06-30 21:07:36 UTC (rev 8479) @@ -77,7 +77,7 @@ tf = datetime.datetime(2000, 1, 20) fig = plt.figure() ax = fig.add_subplot(1,1,1) - ax.set_xlim((t0,tf)) + ax.set_xlim((t0,tf), auto=True) ax.plot([],[]) from matplotlib.dates import DayLocator, DateFormatter, HourLocator ax.xaxis.set_major_locator(DayLocator()) Modified: trunk/matplotlib/lib/matplotlib/widgets.py =================================================================== --- trunk/matplotlib/lib/matplotlib/widgets.py 2010-06-30 16:31:23 UTC (rev 8478) +++ trunk/matplotlib/lib/matplotlib/widgets.py 2010-06-30 21:07:36 UTC (rev 8479) @@ -131,7 +131,7 @@ event.canvas.release_mouse(self.ax) if not self.eventson: return - if event.inaxes != self.ax: + if event.inaxes != self.ax: return for cid, func in self.observers.items(): func(event) @@ -253,10 +253,10 @@ self.drag_active = True event.canvas.grab_mouse(self.ax) - if not self.drag_active: + if not self.drag_active: return - - elif ((event.name == 'button_release_event') + + elif ((event.name == 'button_release_event') or (event.name == 'button_press_event' and event.inaxes != self.ax)): self.drag_active = False event.canvas.release_mouse(self.ax) @@ -1134,7 +1134,7 @@ self.validButtons = button elif isinstance(button, int): self.validButtons = [button] - + assert(spancoords in ('data', 'pixels')) self.spancoords = spancoords @@ -1165,7 +1165,7 @@ if self.validButtons is not None: if not event.button in self.validButtons: return True - + # If no button was pressed yet ignore the event if it was out # of the axes if self.eventpress == None: Modified: trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py =================================================================== --- trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py 2010-06-30 16:31:23 UTC (rev 8478) +++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py 2010-06-30 21:07:36 UTC (rev 8479) @@ -93,8 +93,8 @@ ydwl = (0.95/self.dist) ydw = (0.9/self.dist) - Axes.set_xlim(self, -xdwl, xdw) - Axes.set_ylim(self, -ydwl, ydw) + Axes.set_xlim(self, -xdwl, xdw, auto=None) + Axes.set_ylim(self, -ydwl, ydw, auto=None) def create_axes(self): self.w_xaxis = axis3d.XAxis('x', self.xy_viewLim.intervalx, @@ -361,7 +361,7 @@ button or buttons to use to zoom the 3D axes. Default = 3. ============ ======================================================= - + """ self.button_pressed = None canv = self.figure.canvas @@ -1083,21 +1083,21 @@ dx, dy, dz can be arrays or scalars. *color* can be: - + - A single color value, to color all bars the same color. - + - An array of colors of length N bars, to color each bar independently. - + - An array of colors of length 6, to color the faces of the bars similarly. - + - An array of colors of length 6 * N bars, to color each face independently. When coloring the faces of the boxes specifically, this is the order of the coloring: - + 1. -Z (bottom of box) 2. +Z (top of box) 3. -Y This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |