 # Plotting a matrix in some region

Hi,

today I urgently needed to plot a matrix in a given
region of a plot. It seems that imshow does not
support this (at least I could not find how)
and I don't understand the internals well
enough to add such a feature.
As work-around I have set up the quick hack listed
at the end of this mail.
It is not really complicated, but
maybe it is useful to someone else.

Note, that there are a couple of problems:
- zooming does not work as expected
(the displayed matrix stays fixed in absolute coords wrt to
the current graph)
- drawing a line over the shown bitmap is not possible
- presumably more

Is there a way to this better with imshow?

Best,

Arnd

···

#########################
from pylab import *

def plot_mat(mat,extent=None):
""" Plot a matrix (or whatever suits imshow) at
the place defined by extent=[x0,x1,y0,y1].
"""
g=gca()
l,b,w,h=g.get_position()
x0,x1=g.get_xlim()
y0,y1=g.get_ylim()

#print "Axes coords of curr axes:",l,b,w,h
#print "Ranges:",x0,x1,y0,y1

if extent!=None:
inset_x0=extent
inset_x1=extent
inset_y0=extent
inset_y1=extent
else:
inset_x0=x0
inset_x1=x1
inset_y0=y0
inset_y1=y1

#print "WANTED:",inset_x0,inset_x1,inset_y0,inset_y1

inset_w=w*(inset_x1-inset_x0)/(x1-x0)
inset_h=h*(inset_y1-inset_y0)/(y1-y0)
inset_l=l+(inset_x0-x0)/(x1-x0)*w
inset_b=b+(inset_y0-y0)/(y1-y0)*h

#print "RESULT:",inset_l , inset_b , inset_w , inset_h

ax=axes( [inset_l , inset_b , inset_w , inset_h],axisbg="y")
setp(ax,xticks=[],yticks=[])
imshow(arr,interpolation="nearest")

# 2D
arr=reshape(arange(25),(5,5))

# 1D plot
x=arange(2.0,10.0,0.1)
line1,=plot(x,x**2)
line2,=plot(x,x**2)

#draw()

plot_mat(arr,extent=[5.0,8.0,15.0,50.0])

# Problem: try to plot this over the other plot,
# does not work
setp(line2,data=(x,0.25*x**3),zorder=1000)

show()

today I urgently needed to plot a matrix in a given

> region of a plot. It seems that imshow does not
> support this (at least I could not find how)
> and I don't understand the internals well
> enough to add such a feature.
> As work-around I have set up the quick hack listed
> at the end of this mail.
> It is not really complicated, but
> maybe it is useful to someone else.

If I'm understanding you correctly, you want to set the "extent"
argument of imshow

from pylab import *
arr=reshape(arange(25),(5,5))

imshow(arr, extent=[5.0,8.0,15.0,50.0])
x=arange(2.0,10.0,0.1)
line1,=plot(x,x**2)
line2,=plot(x,x**2)
setp(line2,data=(x,0.25*x**3),zorder=1000)
show()

> Note, that there are a couple of problems:
> - zooming does not work as expected
> (the displayed matrix stays fixed in absolute coords wrt to
> the current graph)
> - drawing a line over the shown bitmap is not possible
> - presumably more

The approach above should fix these three problems.

JDH

···

On 9/1/05, Arnd Baecker <arnd.baecker@...273...> wrote:

Hi John,

It seems things are slightly more complicated, though...

> today I urgently needed to plot a matrix in a given
> region of a plot. It seems that imshow does not
> support this (at least I could not find how)
> and I don't understand the internals well
> enough to add such a feature.
> As work-around I have set up the quick hack listed
> at the end of this mail.
> It is not really complicated, but
> maybe it is useful to someone else.

If I'm understanding you correctly, you want to set the "extent"
argument of imshow

Well, I thought so too, but I also need `axis("equal")`
and depending on the order of setting the
axis intervals (`axis([-0.35,2.1,-0.2,1.25])`)
before or after this, one obtains completely different results.

Below is an example, where this is illustrated,
by changing the code at the places marked by ===>.

So the example I posted was stripped down too strongly
(and your solution does work for that case!).

Best,

Arnd

P.S.: I ran my test with yesterdays CVS.

···

On Thu, 1 Sep 2005, John Hunter wrote:

On 9/1/05, Arnd Baecker <arnd.baecker@...273...> wrote:

###################
from pylab import *

# ===> uncommenting this gives a different result:
#ax=subplot(111,autoscale_on=False)

# ===> changing the order of these two gives different results:
axis("equal")
axis([-0.35,2.1,-0.2,1.25])
# (note that -0.2 and 1.25 are not respected)

arr=reshape(arange(25),(5,5))

# ===> commenting this one out, when autoscale_on=False
# gives the expected result
imshow(arr, extent=[0.5,1.0,0.2,0.8])

# plot a circle to see if the aspect ratio is correct:
phi=arange(0.0,2.0*pi,0.01)
x=0.5*cos(phi)+0.5
y=0.5*sin(phi)+0.5

plot(x,y,lw="8")

show()

Hi John,

I looked a little bit further into this,
and maybe there is a simple solution:

In imshow (axes.py): if I comment out the lines

#corners = (xmin, ymin), (xmax, ymax)
#self.update_datalim(corners)
#self.set_xlim((xmin, xmax))
#self.set_ylim((ymin, ymax))

it works fine for the example I sent yesterday.
(only the different behaviour when changing the order
of `axis("equal")` and `axis([-0.35,2.1,-0.2,1.25])`
persists.)

So maybe it is already enough to encapsulate the above
part by `if autoscale_on==True`?
I am sorry that I can't help more here, but I just don't understand
the internals of matplotlib well enough.

Best,

Arnd