A pox on matplotlib's default reply-to-sender!
Resending my reply that went to Fernando alone below.
> > Why does pylab.matshow() create a new figure by default when no other
> > standard pylab function I know of does that? It seems very
> > inconsistent for no particular gain, since as always
> > figure();matshow(m) will achieve that result if that is what is
> > desired.
>
> No: matshow has to create a figure with a non-standard size so that
> the final figure has the same aspect ratio as the array being
> displayed. If you call figure() first, the figure has already been
> created.
>
> The code:
>
> # Extract actual aspect ratio of array and make appropriately sized figure
> w,h = figaspect(arr)
> fig = figure(fignum,figsize=(w,h))
I guess that makes sense.
Personally I'd rather have consistency. I'm not sure why matshow() in
particular needs to have the window shape match the image shape.
Why not just do axis('scaled') within the confines of the window you have?
Tried it out, it seems to work pretty well, and seems more consistent
with the way other things work in pylab.
def mymatshow(*args,**kw):
"""Display an array as a matrix in a new figure window.
The origin is set at the upper left hand corner and rows (first dimension
of the array) are displayed horizontally. The aspect ratio of the figure
window is that of the array, as long as it is possible to fit it within
your screen with no stretching. If the window dimensions can't accomodate
this (extremely tall/wide arrays), some stretching will inevitably occur.
Tick labels for the xaxis are placed on top by default.
matshow() calls imshow() with args and **kwargs, but by default it sets
interpolation='nearest' (unless you override it). All other arguments and
keywords are passed to imshow(), so see its docstring for further details.
Special keyword arguments which are NOT passed to imshow():
- fignum(None): by default, matshow() creates a new figure window with
automatic numbering. If fignum is given as an integer, the created
figure will use this figure number. Because of how matshow() tries to
set the figure aspect ratio to be the one of the array, if you provide
the number of an already existing figure, strange things may happen.
- returnall(False): by default, the return value is a figure instance.
With 'returnall=True', a (figure, axes, image) tuple is returned.
Example usage:
def samplemat(dims):
aa = zeros(dims)
for i in range(min(dims)):
aa[i,i] = i
return aa
dimlist = [(12,12),(128,64),(64,512),(2048,256)]
for d in dimlist:
fig, ax, im = matshow(samplemat(d))
show()
"""
# Preprocess args for our purposes
arr = asarray(args[0])
# Extract unique keywords we can't pass to imshow
kw = kw.copy()
fignum = popd(kw,'fignum',None)
retall = popd(kw,'returnall',False)
# Extract actual aspect ratio of array and make appropriately sized figure
w,h = figaspect(arr)
#fig = figure(fignum,figsize=(w,h))
fig = gcf()
cla()
ax = fig.add_axes([0.15, 0.09, 0.775, 0.775])
axis('scaled')
ax.xaxis.tick_top()
ax.title.set_y(1.05) # raise it up a bit for tick top
kw['aspect'] = 'auto'
# imshow call: use 'lower' origin (we'll flip axes later)
kw['origin'] = 'lower'
# Unless overridden, don't interpolate
kw.setdefault('interpolation','nearest')
# All other keywords go through to imshow.
im = ax.imshow(*args,**kw)
gci._current = im
# set the x and y lim to equal the matrix dims
nr,nc = arr.shape[:2]
ax.set_xlim((0,nc))
ax.set_ylim((nr,0))
draw_if_interactive()
if retall:
return fig, ax, im
else:
return fig
--bb
···
On 3/17/07, Bill Baxter <wbaxter@...287...> wrote:
On 3/17/07, Fernando Perez <fperez.net@...287...> wrote:
> On 3/16/07, Bill Baxter <wbaxter@...287...> wrote: