> From: C M [mailto:cmpyt...@gmail.com] > Sent: Friday, February 12, 2010 17:15 > > I would like to understand your approach better. So far, I can't get > your code to produce the "margins" indicated--but I'm probably > applying it wrongly. I don't know how to force an autoscale, for > example. Your code is tough for me to understand because there are a > number of things you make use of that I'm not familiar with yet. I > could ask a number of questions but don't want to burden the list with > that unless people are up for it.
Okay. The basic idea is that axes.autoscale_view(tight=False) already has the capacity to obtain whatever view limits are returned by each axis' major tick locator, so we don't need to alter the autoscale_view code within matplotlib; we just implement a locator that yields limits we like. I based my locator on MaxNLocator, but you could use a different base. Only two methods inherited from MaxNLocator need to be modified -- the __init__ method to store the margin, and the view_limits method to implement the looser limits. We attach an instance of the locator to an axis using the axis' set_major_locator method, and if we've already plotted and need to autoscale, we invoke axes.autoscale_view. To later change the margin (or the parameters handled by MaxNLocator), we can attach a new instance. I updated my code for matplotlib 0.99.1, added some comments and examples, and have attached it below. I hope it's helpful as an example. ---- import numpy as np import matplotlib as mpl import matplotlib.ticker as mticker import matplotlib.transforms as mtransforms class LooseMaxNLocator(mticker.MaxNLocator): """ Select no more than N intervals at nice locations with view limits loosely fitted to the data. Unlike MaxNLocator, the view limits do not necessarily coincide with tick locations. """ def __init__(self, margin = 0.0, **kwargs): """ Keyword arguments: *margin* Specifies the minimum size of both the lower and upper margins (between the view limits and the data limits) as a fraction of the data range. Must be non-negative. Remaining keyword arguments are passed to MaxNLocator. """ mticker.MaxNLocator.__init__(self, **kwargs) if margin < 0: raise ValueError('The margin must be non-negative.') self._margin = margin def view_limits(self, dmin, dmax): # begin partial duplication of MaxNLocator.view_limits if self._symmetric: maxabs = max(abs(dmin), abs(dmax)) dmin = -maxabs dmax = maxabs dmin, dmax = mtransforms.nonsingular(dmin, dmax, expander=0.05) # end duplication margin = self._margin * (dmax - dmin) # fraction of data range vmin = dmin - margin # expand the view vmax = dmax + margin bin_boundaries = self.bin_boundaries(vmin, vmax) # locate ticks with MaxNLocator # Note: If the lines below change vmin or vmax, the bin boundaries # later calculated by MaxNLocator.__call__ may differ from those # calculated here. vmin = min(vmin, max(bin_boundaries[bin_boundaries <= dmin])) # expand view to the highest tick below or touching the data vmax = max(vmax, min(bin_boundaries[bin_boundaries >= dmax])) # expand view to the lowest tick above or touching the data return np.array([vmin, vmax]) # Examples import matplotlib.pyplot as plt fig1 = plt.figure() ax1 = fig1.add_subplot(1, 1, 1) ax1.set_xlabel('default locator') ax1.set_ylabel('LooseMaxNLocator') ax1.yaxis.set_major_locator( LooseMaxNLocator(nbins=9, steps=[1, 2, 5, 10], margin=0.125)) # Set our locator before we plot. ax1.plot([0, 0.95], [0, 0.95]) # Our locator's view limits are used. fig2 = plt.figure() ax2 = fig2.add_subplot(1, 1, 1) ax2.set_xlabel('default locator') ax2.set_ylabel('LooseMaxNLocator') ax2.plot([0, 1.05], [0, 1.05]) # The default locator's view limits are used. ax2.yaxis.set_major_locator( LooseMaxNLocator(nbins=9, steps=[1, 2, 5, 10], margin=0.125)) # Now set our locator. ax2.autoscale_view() # Autoscale activates our locator's view limits. ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users