[matplotlib-devel] Is there a way to link axes of imshow plots?

Has anybody given any further thought to the implication
of having Basemap set adjustable as “box-forced” instead of “box”? So
far, it has been working just fine for me, but I have no clue if there
are any unintended side-effects.

Ben Root

Ben: To summarize the discussion so far, it seems that “box-forced”
should not be used, and either Basemap should continue to use
adjustable=“box” (for the reasons Eric gave in his post yesterday) or
adjustable should not be set at all by Basemap and that job should be
left to the user (since adjustable=‘box’ is the default anyway, as
Jae-Joon pointed out today). Perhaps it would help if you could
provide a usage example for AxesGrid axes sharing with Basemap, so we
can see what the consequences of changing the current behavior are.

-Jeff

···
-- Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : 325 Broadway Office : Skaggs Research Cntr 1D-113
Boulder, CO, USA 80303-3328 Web :

Jeffrey.S.Whitaker@…259…http://tinyurl.com/5telg

Has anybody given any further thought to the implication
of having Basemap set adjustable as “box-forced” instead of “box”? So
far, it has been working just fine for me, but I have no clue if there
are any unintended side-effects.

Ben Root

Ben: To summarize the discussion so far, it seems that “box-forced”
should not be used, and either Basemap should continue to use
adjustable=“box” (for the reasons Eric gave in his post yesterday) or
adjustable should not be set at all by Basemap and that job should be
left to the user (since adjustable=‘box’ is the default anyway, as
Jae-Joon pointed out today). Perhaps it would help if you could
provide a usage example for AxesGrid axes sharing with Basemap, so we
can see what the consequences of changing the current behavior are.

-Jeff

Jeff,

Maybe it isn’t a use-case per se, but I have found that it is much
easier to use axes_grid1 instead of subplots to produce multiple radar
plots that all use the same colorbar. For example, I have 3 radar
plots to show, and I want a single colorbar on the right-hand side. To
a newbie, one would add three subplots with a .colorbar() command for
the last one. Unfortunately, the newbie will discover that the third
plot will be smaller than the other two because that last axes has to
be split between two objects. To someone a little more advanced, you
would create 4 subplots, but fool around with the size of the last axes
(and also have to discover to use ColorbarBase instead of the regular
colorbar call).

But, with axes_grid, this is quite trivial and the results look very nice.

This is a png image of a time series I recently included for a publication shows the result using AxesGrid: http://dl.dropbox.com/u/7325604/NWRT_TimeSeries.png

Ben Root

P.S.

  • I have found a ‘bug’ of sorts with using ‘box-forced’ for Basemap and
    AxesGrid. For the displayed plot, if one were to zoom in on one of the
    plots, the other plots will zoom in as well (which I think is neat),
    but they won’t update their bbox to completely match the zoomed-in
    axes. I guess this would be an argument against using ‘box-forced’?
···

On Thu, Jun 10, 2010 at 11:05 AM, Jeff Whitaker <jswhit@…878…146…> wrote:

On 6/9/10 1:58 PM, Benjamin Root wrote:

On Tue, Jun 1, 2010 at 6:00 PM, Benjamin > > Root <ben.root@…1304…> wrote:

Right,
that is sort of what I am asking. My thinking is that Basemap could
use ‘box-forced’ instead of ‘box’ for the adjustable parameter in order
to make it and AxesGrid compatible. Usually, if one wants to use
AxesGrid, they all should have the same domain and aspect ratio. I
just have no clue what sort of repricussions that has for other use
cases.

So far, this has worked just fine for me, but I hardly represent the
normal use cases of Basemap and AxesGrid.

Ben Root

On Tue, Jun 1, 2010 at 5:20 PM, Jae-Joon > > > Lee <lee.j.joon@…287…> > > > wrote:

If
Basemap explicitly sets aspect=1 and adjustable=“box” at the same

time, you cannot use this with any axes that shares its axis with

others (including the axes created by the AxesGrid).

You need to somehow avoid the set_aspect call with adjustable"box"

(you can set box-forced in stead).

-JJ

On Tue, Jun 1, 2010 at 2:45 PM, Benjamin Root <ben.root@…1304…> > > > > wrote:

On a related note, I have noticed an incompatibility between
AxesGrid and

Basemap. It appears that Basemap will explicitly set
adjustable=‘box’ when

it calls ax.set_aspect(), but AxesGrid will error out, saying that
it has to

be ‘datalim’. What are the implications of using ‘box-forced’
instead of

‘box’ in Basemap?

Ben Root

On Thu, May 27, 2010 at 1:59 PM, Jae-Joon Lee <lee.j.joon@…287…> wrote:

ax1 = subplot(121)

ax2 = subplot(122, sharex=ax1, sharey=ax1)

ax1.set_adjustable(“box-forced”)

ax2.set_adjustable(“box-forced”)

arr1 = np.arange(100).reshape((10, 10))

ax1.imshow(arr1)

arr2 = np.arange(100, 0, -1).reshape((10, 10))

ax2.imshow(arr2)

Note the use of set_adjustable(“box-forced”).

sharex and sharey does not get along with axes of aspect=1
&

adjustable=“box”.

-JJ

On Thu, May 27, 2010 at 2:10 PM, <PHobson@…2850…> > > > > wrote:

Do the “sharex” and “sharey” kwargs help?

http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.axes

http://matplotlib.sourceforge.net/examples/pylab_examples/shared_axis_demo.html

-paul

From: Adam Fraser [mailto:adam.n.fraser@…287…]

Sent: Thursday, May 27, 2010 10:44 AM

To: matplotlib-users

Subject: [Matplotlib-users] Is there a way to link axes
of imshow plots?

Suppose I have a figure canvas with 3 plots… 2 are
images of the same

dimensions plotted with imshow, and the other is a
scatterplot. I’d like

to

be able to link the x and y axes of the imshow plots so
that when I zoom

in

one, the other zooms to the same coordinates, and when I
pan in one, the

other pans as well.

I started hacking my way around this by

subclassing NavigationToolbar2WxAgg

(shown below)… but there are several problems here.

  1. This will link the axes of all plots in a canvas since
    all I’ve done

is

get rid of the checks for a.in_axes()

  1. This worked well for panning, but zooming caused all
    subplots to zoom

from the same global point, rather than from the same
point in each of

their

respective axes.

Can anyone suggest a workaround?

Much thanks!

-Adam

from matplotlib.backends.backend_wxagg import
NavigationToolbar2WxAgg as

NavigationToolbar

class MyNavToolbar(NavigationToolbar):

def __init__(self, canvas, cpfig):
    NavigationToolbar.__init__(self, canvas)
# override
def press_pan(self, event):
    'the press mouse button in pan/zoom mode callback'
    if event.button == 1:
        self._button_pressed=1
    elif  event.button == 3:
        self._button_pressed=3
    else:
        self._button_pressed=None
        return
    x, y = event.x, event.y
    # push the current view to define home if stack

is empty

    if self._views.empty(): self.push_current()
    self._xypress=[]
    for i, a in

enumerate(self.canvas.figure.get_axes()):

        # only difference from overridden method is

that this one

doesn’t

        # check a.in_axes(event)
        if x is not None and y is not None and

a.get_navigate():

            a.start_pan(x, y, event.button)
            self._xypress.append((a, i))
            self.canvas.mpl_disconnect(self._idDrag)

self._idDrag=self.canvas.mpl_connect(‘motion_notify_event’,

self.drag_pan)

def press_zoom(self, event):
    'the press mouse button in zoom to rect mode

callback’

    if event.button == 1:
        self._button_pressed=1
    elif  event.button == 3:
        self._button_pressed=3
    else:
        self._button_pressed=None
        return
    x, y = event.x, event.y
    # push the current view to define home if stack

is empty

    if self._views.empty(): self.push_current()
    self._xypress=[]
    for i, a in

enumerate(self.canvas.figure.get_axes()):

        # only difference from overridden method is

that this one

doesn’t

        # check a.in_axes(event)
        if x is not None and y is not None and

a.get_navigate() and

a.can_zoom():

            self._xypress.append(( x, y, a, i,

a.viewLim.frozen(),

a.transData.frozen()))

    self.press(event)


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users



Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users



Matplotlib-devel mailing list

Matplotlib-devel@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-devel



Matplotlib-devel mailing list

  Matplotlib-devel@lists.sourceforge.net

  [https://lists.sourceforge.net/lists/listinfo/matplotlib-devel](https://lists.sourceforge.net/lists/listinfo/matplotlib-devel)
-- Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : Jeffrey.S.Whitaker@...259...
325 Broadway Office : Skaggs Research Cntr 1D-113
Boulder, CO, USA 80303-3328 Web : [http://tinyurl.com/5telg](http://tinyurl.com/5telg)

By default, x-axis is shared along the axes in a same column and
y-axis is shared along the axes in a same raw. i.e., in your example,
only the y-axis are shared which I think is the source of your issue.

http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/users/overview.html#axesgrid

I think what you want is to use share_all=True.

grid = AxesGrid(fig, 111,
                nrows_ncols=(1, 3),
                axes_pad=0.1,
                share_all=True,
                cbar_mode='single',
                cbar_pad=0.05,
                cbar_size=0.08,
                )

Is this solve your problem?
Regards,

-JJ

···

On Thu, Jun 10, 2010 at 12:47 PM, Benjamin Root <ben.root@...1304...> wrote:

P.S. - I have found a 'bug' of sorts with using 'box-forced' for Basemap and
AxesGrid. For the displayed plot, if one were to zoom in on one of the
plots, the other plots will zoom in as well (which I think is neat), but
they won't update their bbox to completely match the zoomed-in axes. I
guess this would be an argument against using 'box-forced'?

Thanks Jae-Joon: Since I couldn't see any problem with removing adjustable='box' from Basemap, I went ahead and did it (and added an example that uses AxesGrid). AFAICT, a problem will only occur if the user explicit does ax_set_adjustable('datalim').

-Jeff

···

On 6/10/10 12:00 PM, Jae-Joon Lee wrote:

On Thu, Jun 10, 2010 at 12:47 PM, Benjamin Root<ben.root@...1304...> wrote:
   

P.S. - I have found a 'bug' of sorts with using 'box-forced' for Basemap and
AxesGrid. For the displayed plot, if one were to zoom in on one of the
plots, the other plots will zoom in as well (which I think is neat), but
they won't update their bbox to completely match the zoomed-in axes. I
guess this would be an argument against using 'box-forced'?
     

By default, x-axis is shared along the axes in a same column and
y-axis is shared along the axes in a same raw. i.e., in your example,
only the y-axis are shared which I think is the source of your issue.

http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/users/overview.html#axesgrid

I think what you want is to use share_all=True.

grid = AxesGrid(fig, 111,
                 nrows_ncols=(1, 3),
                 axes_pad=0.1,
                 share_all=True,
                 cbar_mode='single',
                 cbar_pad=0.05,
                 cbar_size=0.08,
                 )

Is this solve your problem?
Regards,

-JJ
   
--
Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : Jeffrey.S.Whitaker@...259...
325 Broadway Office : Skaggs Research Cntr 1D-113
Boulder, CO, USA 80303-3328 Web : http://tinyurl.com/5telg

Not that it was a “problem” per se, just merely an observation I had. Anyway, I tried that and indeed, zooming on one box zoomed all of the other boxes the same way. Might be good to include in the basemap examples, maybe?

Thanks,
Ben Root

···

On Thu, Jun 10, 2010 at 1:00 PM, Jae-Joon Lee <lee.j.joon@…287…> wrote:

On Thu, Jun 10, 2010 at 12:47 PM, Benjamin Root <ben.root@…1304…> wrote:

P.S. - I have found a ‘bug’ of sorts with using ‘box-forced’ for Basemap and

AxesGrid. For the displayed plot, if one were to zoom in on one of the

plots, the other plots will zoom in as well (which I think is neat), but

they won’t update their bbox to completely match the zoomed-in axes. I

guess this would be an argument against using ‘box-forced’?

By default, x-axis is shared along the axes in a same column and

y-axis is shared along the axes in a same raw. i.e., in your example,

only the y-axis are shared which I think is the source of your issue.

http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/users/overview.html#axesgrid

I think what you want is to use share_all=True.

grid = AxesGrid(fig, 111,

            nrows_ncols=(1, 3),

            axes_pad=0.1,

            share_all=True,

            cbar_mode='single',

            cbar_pad=0.05,

            cbar_size=0.08,

            )

Is this solve your problem?

Regards,

-JJ

Ben: I’ve added a new example (fcstmaps_axesgrid.py) that does this.

-Jeff

···
-- Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : 325 Broadway Office : Skaggs Research Cntr 1D-113
Boulder, CO, USA 80303-3328 Web :

Jeffrey.S.Whitaker@…259…http://tinyurl.com/5telg