Motivated in part by an old patch (1233294) submitted to sourceforge by Nikolai Hlubek, I took a look at how aspect ratio is handled in mpl, and concluded it wasn't quite right:
1) The aspect='preserve' kwarg in image caused the image to retain its aspect ratio only with some resize events, not with all. The implementation in the image.py code does not look right to me.
2) The aspect='equal' kwarg in axes.py did not respond to resize events at all.
3) I could not understand why there should be separate "aspect" kwargs for image and for axes.
Therefore I have reworked the aspect-handling code in axes.py, and I think it is working reasonably well. Indeed, I don't see any remaining need for an "aspect" kwarg in image.py, and I would like to take it out unless someone raises an objection.
I have also changed the aspect-related API to make it more flexible and self-explanatory:
def set_aspect(self, aspect='auto', fixLimits=None,
'auto' - automatic; fill position rectangle with data
'normal' - same as 'auto'; deprecated
'equal' - same scaling from data to plot units for x and y
A - a circle will be stretched such that the height
is A times the width. aspect=1 is the same as
'position' - change width or height of bounding rectangle;
keep it centered.
'box_size' - as above, but anchored to lower left
'datalim' - change xlim or ylim
fixLimits: deprecated; False is aspect_adjusts='datalim';
True is aspect_adjusts='position'
ACCEPTS: ['auto' | 'equal' | aspect_ratio]
def set_aspect_adjusts(self, aspect_adjusts = 'position'):
Must be called after set_aspect.
ACCEPTS: ['position' | 'box_size' | 'datalim']
Anticipating that some additional work will need to be done, I have not yet made an entry in the CHANGELOG or API_CHANGES.
In addition to removing the aspect kwarg from image.py, I would like to take fixLimits out of set_aspect (above). No code in mpl or its examples depends on it, but this might break some user code, so for the present I have maintained compatibility.
One question: is there an easy way to automatically trigger a redraw in an interactive backend (e.g. ipython with gtkagg) at the end of the set_aspect() method, for example? The way it works now is that one can make a plot, call the set_aspect() method on the resulting axes object, and the result will appear as soon as the window is manipulated with the mouse; but this manipulation is needed to trigger a redraw.