plotting using an image as background

Hi there,
I am all new to mathlib world..

What I try to do is plotting some charts over an image.
I would be very grateful, if somebody could provide me with an example.
thanks
robert

Hi there,

I am all new to mathlib world…

What I try to do is plotting some charts over an image.

I would be very grateful, if somebody could provide me with an example.

thanks

robert

Welcome Robert,

This is fairly straight-forward. If you have a image file, you can plot it like so:

import matplotlib.pyplot as plt
imData = plt.imread(“foobar.png”)

plt.imshow(imData)

Now, the tricky issue is that the coordinate system for the plot may be a bit backwards than you might want for normal plotting. The (0, 0) coordinate will be in the upper-left instead of the lower-left. Plus, the axis limits will be in pixels. This may or may not be an issue depending on what you plan to plot on top of the image. And, of course, unless you are in interactive mode, you will need to do a “plt.show()” call when you are finished building the plot and want to display it to the screen.

I hope this helps and let us know if you have any other questions!
Ben Root

···

On Fri, Jul 15, 2011 at 10:49 AM, robert <robert@…3681…> wrote:

thank a lot Ben,

it feels really good when you get answers that fast ..

one more question: can I as imData what dimensions it has?

thanks

robert
···

On 15.07.2011 17:56, Benjamin Root wrote:

    On Fri, Jul 15, 2011 at 10:49 AM, robert > <robert@...3680...> >         wrote:

Hi there,

      I am all new to mathlib world..



      What I try to do is plotting some charts over an image.

      I would be very grateful, if somebody could provide me with an

example.

      thanks

      robert
      Welcome Robert,



      This is fairly straight-forward.  If you have a image file,

you can plot it like so:

      >>> import matplotlib.pyplot as plt

      >>> imData = plt.imread("foobar.png")

      >>> plt.imshow(imData)



      Now, the tricky issue is that the coordinate system for the

plot may be a bit backwards than you might want for normal
plotting. The (0, 0) coordinate will be in the upper-left
instead of the lower-left. Plus, the axis limits will be in
pixels. This may or may not be an issue depending on what you
plan to plot on top of the image. And, of course, unless you
are in interactive mode, you will need to do a “plt.show()”
call when you are finished building the plot and want to
display it to the screen.

      I hope this helps and let us know if you have any other

questions!

      Ben Root

Hi there,

      I am all new to mathlib world..



      What I try to do is plotting some charts over an image.

      I would be very grateful, if somebody could provide me with an

example.

      thanks

      robert
      Welcome Robert,



      This is fairly straight-forward.  If you have a image file,

you can plot it like so:

      >>> import matplotlib.pyplot as plt

      >>> imData = plt.imread("foobar.png")

      >>> plt.imshow(imData)



      Now, the tricky issue is that the coordinate system for the

plot may be a bit backwards than you might want for normal
plotting. The (0, 0) coordinate will be in the upper-left
instead of the lower-left. Plus, the axis limits will be in
pixels. This may or may not be an issue depending on what you
plan to plot on top of the image. And, of course, unless you
are in interactive mode, you will need to do a “plt.show()”
call when you are finished building the plot and want to
display it to the screen.

      I hope this helps and let us know if you have any other

questions!

      Ben Root

thank a lot Ben,

it feels really good when you get answers that fast ..

one more question: can I as imData what dimensions it has?



thanks

robert

That is quite straight-forward:

print imData.shape

matplotlib uses NumPy for its numerical data arrays. You might want to read up on its documentation here:

http://docs.scipy.org/doc/numpy/user/

http://docs.scipy.org/doc/numpy/reference/

I hope this helps!
Ben Root

···

On Fri, Jul 15, 2011 at 11:42 AM, robert rottermann <robert@…3680…> wrote:

On 15.07.2011 17:56, Benjamin Root wrote:

    On Fri, Jul 15, 2011 at 10:49 AM, robert > > <robert@...3680...> > >         wrote:

Hi Robert,

Hi there,

I am all new to mathlib world…

What I try to do is plotting some charts over an image.

I would be very grateful, if somebody could provide me with an example.

thanks

robert

I just did this myself with this code:

def make_cutouts(h5file, band=1, vmin=None, vmax=None, dir=’.’):

"""Browse pixel data by pixel selection

A shift-left-click on a pixel in ``image`` creates a plot of

the response data for that pixel. A shift--click on the
resulting plot will save it to two files in ``dir`` whose names

are of the form cutout-xcen-ycen.{dat,png}, where xcen and ycen
are replaced with the location of image center. The png file is

an rgb img, the dat file is raw uint16 data.

Parameters
···

On Fri, Jul 15, 2011 at 9:49 AM, robert <robert@…3680…> wrote:

----------
h5file : string

    Path to h5 file containing image data.
band : int

    Band to use. Must be 0 or 1.
vmax, vmin : float, optional

    Maximum and minimum values to which the image will be scaled.
dir : string, optional

    Path to directory in which plots will be saved.

"""

import matplotlib.pyplot as plt
import h5py

from widgets import Button

# get image data here so that it gets compiled into onclick

fin = h5py.File(h5file, 'r')
img = fin['band%d' % band][...]

src = fin['/'].attrs['input_filename']
fin.close()

m, n = img.shape
# make points for drawing square cutout

xcor = np.array([-128,  128, 128, -128, -128], dtype=float)/10
ycor = np.array([-128, -128, 128,  128, -128], dtype=float)/10

def save(fig, mouse, data):
    def onclick(event):

        if event.button == 1:
            xcen = mouse.xdata

            ycen = mouse.ydata
            i = int(xcen + .5)*10

            j = int(ycen + .5)*10

            # write data to file

            path = os.path.join(dir, 'cutout-%05d-%05d' % (i,j))
            fout = h5py.File(path + '.h5', 'w')

            fout.create_dataset('image', data.shape, data.dtype)
            fout['/'].attrs['input_filename'] = src

            fout['/'].attrs['x_center_pixel'] = i
            fout['/'].attrs['y_center_pixel'] = j

            fout['image'][...] = data
            fout.close()

            fig.savefig(path + ".png")
            # draw square around cutout

            mouse.inaxes.plot(xcen + xcor, ycen + ycor, 'r', lw=2)
            mouse.canvas.draw()

    return onclick

def onclick(event):
    mouse = event.mouseevent

    if mouse.button == 1 and mouse.key == "shift":
        i = int(mouse.xdata + .5)*10

        j = int(mouse.ydata + .5)*10
        src_axs = mouse.inaxes

        ul_x = max(0, i - 128)
        ul_y = max(0, j - 128)

        lr_x = min(n, i + 128)
        lr_y = min(m, j + 128)

        data = img[ul_y:lr_y, ul_x:lr_x]
        #

        newfig = plt.figure()
        newfig.subplots_adjust(top=.90)

        # add save button
        butax = newfig.add_axes([0.45, .92, .1, 0.04])

        button = Button(butax, 'Save', color='red', hovercolor='gold')
        button.on_clicked(save(fig, mouse, data))

        # display image of cutout
        axs = newfig.add_subplot(111)

        tmp = axs.imshow(data)
        newfig.colorbar(tmp)

        newfig.show()

fig = plt.figure()

axs = fig.add_subplot(111)
tmp = axs.imshow(img[::10, ::10], vmin=vmin, vmax=vmax, origin='lower', picker=True)

xmin, xmax, ymin, ymax = np.array(tmp.get_extent()) + .5
axs.set_xticks([t for t in axs.get_xticks() if t >= 0 and t <= xmax])

axs.set_yticks([t for t in axs.get_yticks() if t >= 0 and t <= ymax])

fig.canvas.mpl_connect("pick_event", onclick)
fig.show()

Which is probably more complex than what you need. What it does is display a thumbnail of a very large image on which you can shift-click to blowup a 256x256 portion in a separate figure. If you then click the (custom) save button on the blowup it saves the data together with a thumbnail and plots a square around the cutout pixels in the original image. The tricky part is that the image axis generally starts at -.5 and this will cause problems as the plot will want to put up it’s own ticks that excede the image bounds and you will get big white borders where you don’t want them. Hence I call axs.set_xticks etc. to remove the offending ticks. To bad the image itself doesn’t make its own ticks available.

I had to rewrite the button code to make this work as the first click handler takes the button with it when it exits as the figure doesn’t keep a reference to it, but that is another problem :wink:

Chuck