Using callbacks to change Axes positions

Hi,

I am trying to set up a colorbar that automatically resizes if I zoom in to an image (which changes the aspect ratio of the axes, so I want the colorbar to get resized too). Let's say I have two Axes instances, say ax (for the main image) and cax (for the colorbar). I can set up a callback if the view limits in one axes change, for example

ax.callbacks.connect('xlim_changed', update_colorbar)
ax.callbacks.connect('ylim_changed', update_colorbar)

Now I can store a reference to cax inside ax:

ax._cax = cax

And I can now define update_colorbar so that it basically changes the position of cax:

def update_colorbar(ax):

    # Get current position
    xmin = ax..get_position().xmin
    ...

    # Compute new colorbar position
    ...

    # Set new position
    ax._cax.set_position(...)

    # Return axes instance
    return ax

Now the issue is that if I select a region of the image to zoom into, then as soon as I've selected the region, update_colorbar gets called, but by then, the aspect ratio of ax hasn't changed, and so the position I find when I do xmin = ax..get_position().xmin in update_colorbar is the *old* position of ax, not the new one. So the colorbar position is always one step behind compared to the main image axes.

Can anyone think of any way that would avoid this issue, and to be able to use the *new* position of ax inside update_colorbar?

Thanks in advance for any help,

Thomas

see

http://www.mail-archive.com/matplotlib-users@lists.sourceforge.net/msg15919.html

axes_grid toolkit provides some helper function that utilizes
axes_locator (take a look at demo_locatable_axes_easy function in the
example below)

http://matplotlib.sourceforge.net/examples/axes_grid/demo_axes_divider.html

-JJ

···

On Thu, Mar 4, 2010 at 9:05 PM, Thomas Robitaille <thomas.robitaille@...287...> wrote:

Hi,

I am trying to set up a colorbar that automatically resizes if I zoom in to an image (which changes the aspect ratio of the axes, so I want the colorbar to get resized too). Let's say I have two Axes instances, say ax (for the main image) and cax (for the colorbar). I can set up a callback if the view limits in one axes change, for example

ax.callbacks.connect('xlim_changed', update_colorbar)
ax.callbacks.connect('ylim_changed', update_colorbar)

Now I can store a reference to cax inside ax:

ax._cax = cax

And I can now define update_colorbar so that it basically changes the position of cax:

def update_colorbar(ax):

# Get current position
xmin = ax..get_position().xmin
...

# Compute new colorbar position
...

# Set new position
ax._cax.set_position(...)

# Return axes instance
return ax

Now the issue is that if I select a region of the image to zoom into, then as soon as I've selected the region, update_colorbar gets called, but by then, the aspect ratio of ax hasn't changed, and so the position I find when I do xmin = ax..get_position().xmin in update_colorbar is the *old* position of ax, not the new one. So the colorbar position is always one step behind compared to the main image axes.

Can anyone think of any way that would avoid this issue, and to be able to use the *new* position of ax inside update_colorbar?

Thanks in advance for any help,

Thomas
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Hi Jae-Joon,

Thanks! This is exactly what I needed. Putting the colorbar on the right or bottom works great - however, I am running into issues with trying to put the colorbar on the left or bottom (which, from my understanding, is controlled by using pack_start=True?). Should the following code work?

import matplotlib.pyplot as mpl
import numpy as np
from mpl_toolkits.axes_grid import make_axes_locatable

fig = mpl.figure()
ax = fig.add_subplot(1,1,1)
divider = make_axes_locatable(ax)
cax = divider.new_horizontal(size="5%", pad=0.05, pack_start=True)
fig.add_axes(cax)
image = ax.imshow(np.random.random((100,100)))
cb = fig.colorbar(image, cax=cax)

Cheers,

Thomas

···

On Mar 4, 2010, at 10:28 PM, Jae-Joon Lee wrote:

see

Re: [Matplotlib-users] Transform problem with fixed aspect ratio

axes_grid toolkit provides some helper function that utilizes
axes_locator (take a look at demo_locatable_axes_easy function in the
example below)

http://matplotlib.sourceforge.net/examples/axes_grid/demo_axes_divider.html

-JJ

On Thu, Mar 4, 2010 at 9:05 PM, Thomas Robitaille > <thomas.robitaille@...287...> wrote:

Hi,

I am trying to set up a colorbar that automatically resizes if I zoom in to an image (which changes the aspect ratio of the axes, so I want the colorbar to get resized too). Let's say I have two Axes instances, say ax (for the main image) and cax (for the colorbar). I can set up a callback if the view limits in one axes change, for example

ax.callbacks.connect('xlim_changed', update_colorbar)
ax.callbacks.connect('ylim_changed', update_colorbar)

Now I can store a reference to cax inside ax:

ax._cax = cax

And I can now define update_colorbar so that it basically changes the position of cax:

def update_colorbar(ax):

   # Get current position
   xmin = ax..get_position().xmin
   ...

   # Compute new colorbar position
   ...

   # Set new position
   ax._cax.set_position(...)

   # Return axes instance
   return ax

Now the issue is that if I select a region of the image to zoom into, then as soon as I've selected the region, update_colorbar gets called, but by then, the aspect ratio of ax hasn't changed, and so the position I find when I do xmin = ax..get_position().xmin in update_colorbar is the *old* position of ax, not the new one. So the colorbar position is always one step behind compared to the main image axes.

Can anyone think of any way that would avoid this issue, and to be able to use the *new* position of ax inside update_colorbar?

Thanks in advance for any help,

Thomas
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Hi Jae-Joon,

I am encountering another issue, when using the method you suggest in combination with the parasite_axes from the matplotlib toolkit:

···

---

import matplotlib.pyplot as mpl
import numpy as np
from mpl_toolkits.axes_grid import make_axes_locatable
import mpl_toolkits.axes_grid.parasite_axes as mpltk
    
fig = mpl.figure()

ax = mpltk.SubplotHost(fig, 1, 1, 1)
fig.add_axes(ax)

divider = make_axes_locatable(ax)

cax = divider.new_horizontal(size="5%", pad=0.05)
fig.add_axes(cax)

image = ax.imshow(np.random.random((100,100)))

cb = fig.colorbar(image, cax=cax)

---

In the above case, the labels end up on the wrong side of the plot, and the usual method for changing the label position, e.g.:

for tick in cax.xaxis.get_major_ticks():
  tick.tick1On = True
  tick.tick2On = True
  tick.label1On = False
  tick.label2On = True

does not work. Do you have any idea why this might be?

Thanks for any help,

Thomas

On Mar 4, 2010, at 10:28 PM, Jae-Joon Lee wrote:

see

Re: [Matplotlib-users] Transform problem with fixed aspect ratio

axes_grid toolkit provides some helper function that utilizes
axes_locator (take a look at demo_locatable_axes_easy function in the
example below)

http://matplotlib.sourceforge.net/examples/axes_grid/demo_axes_divider.html

-JJ

On Thu, Mar 4, 2010 at 9:05 PM, Thomas Robitaille > <thomas.robitaille@...287...> wrote:

Hi,

I am trying to set up a colorbar that automatically resizes if I zoom in to an image (which changes the aspect ratio of the axes, so I want the colorbar to get resized too). Let's say I have two Axes instances, say ax (for the main image) and cax (for the colorbar). I can set up a callback if the view limits in one axes change, for example

ax.callbacks.connect('xlim_changed', update_colorbar)
ax.callbacks.connect('ylim_changed', update_colorbar)

Now I can store a reference to cax inside ax:

ax._cax = cax

And I can now define update_colorbar so that it basically changes the position of cax:

def update_colorbar(ax):

   # Get current position
   xmin = ax..get_position().xmin
   ...

   # Compute new colorbar position
   ...

   # Set new position
   ax._cax.set_position(...)

   # Return axes instance
   return ax

Now the issue is that if I select a region of the image to zoom into, then as soon as I've selected the region, update_colorbar gets called, but by then, the aspect ratio of ax hasn't changed, and so the position I find when I do xmin = ax..get_position().xmin in update_colorbar is the *old* position of ax, not the new one. So the colorbar position is always one step behind compared to the main image axes.

Can anyone think of any way that would avoid this issue, and to be able to use the *new* position of ax inside update_colorbar?

Thanks in advance for any help,

Thomas
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Hi,

It turns out to be a bug (new_vertical works, but new_horizontal does not).
To work around this

right after

cax = divider.new_horizontal(size="5%", pad=0.05, pack_start=True)

add these lines

locator = divider.new_locator(nx=0, ny=0)
cax.set_axes_locator(locator)

These two lines only need to be executed when "new_horizontal" is
called with pack_start=True.

The code below does some monkey patching to fix this bug. Use this if
it fits your need.

Regards,

-JJ

# work around new_horizontal bug
from mpl_toolkits.axes_grid.axes_divider import AxesDivider
if not hasattr(AxesDivider, "_new_horizontal_bug_fixed"):
    new_horizontal_orig = AxesDivider.new_horizontal
    def new_horizontal(self, size, pad=None, pack_start=False, **kwargs):
        ax = new_horizontal_orig(self, size, pad=pad,
                                 pack_start=pack_start, **kwargs)
        if pack_start:
            locator = self.new_locator(nx=0, ny=0)
            ax.set_axes_locator(locator)
        return ax

    AxesDivider.new_horizontal = new_horizontal
    AxesDivider._new_horizontal_bug_fixed = True

···

On Fri, Mar 5, 2010 at 9:05 AM, Thomas Robitaille <thomas.robitaille@...287...> wrote:

Hi Jae-Joon,

Thanks! This is exactly what I needed. Putting the colorbar on the right or bottom works great - however, I am running into issues with trying to put the colorbar on the left or bottom (which, from my understanding, is controlled by using pack_start=True?). Should the following code work?

import matplotlib.pyplot as mpl
import numpy as np
from mpl_toolkits.axes_grid import make_axes_locatable

fig = mpl.figure()
ax = fig.add_subplot(1,1,1)
divider = make_axes_locatable(ax)
cax = divider.new_horizontal(size="5%", pad=0.05, pack_start=True)
fig.add_axes(cax)
image = ax.imshow(np.random.random((100,100)))
cb = fig.colorbar(image, cax=cax)

Cheers,

Thomas

On Mar 4, 2010, at 10:28 PM, Jae-Joon Lee wrote:

see

Re: [Matplotlib-users] Transform problem with fixed aspect ratio

axes_grid toolkit provides some helper function that utilizes
axes_locator (take a look at demo_locatable_axes_easy function in the
example below)

http://matplotlib.sourceforge.net/examples/axes_grid/demo_axes_divider.html

-JJ

On Thu, Mar 4, 2010 at 9:05 PM, Thomas Robitaille >> <thomas.robitaille@...287...> wrote:

Hi,

I am trying to set up a colorbar that automatically resizes if I zoom in to an image (which changes the aspect ratio of the axes, so I want the colorbar to get resized too). Let's say I have two Axes instances, say ax (for the main image) and cax (for the colorbar). I can set up a callback if the view limits in one axes change, for example

ax.callbacks.connect('xlim_changed', update_colorbar)
ax.callbacks.connect('ylim_changed', update_colorbar)

Now I can store a reference to cax inside ax:

ax._cax = cax

And I can now define update_colorbar so that it basically changes the position of cax:

def update_colorbar(ax):

# Get current position
xmin = ax..get_position().xmin
...

# Compute new colorbar position
...

# Set new position
ax._cax.set_position(...)

# Return axes instance
return ax

Now the issue is that if I select a region of the image to zoom into, then as soon as I've selected the region, update_colorbar gets called, but by then, the aspect ratio of ax hasn't changed, and so the position I find when I do xmin = ax..get_position().xmin in update_colorbar is the *old* position of ax, not the new one. So the colorbar position is always one step behind compared to the main image axes.

Can anyone think of any way that would avoid this issue, and to be able to use the *new* position of ax inside update_colorbar?

Thanks in advance for any help,

Thomas
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Unfortunately, axes_grid toolkit (in most cases) creates an axes using
its own Axes class by default. Here is some more details.

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

To use mpl's original Axes class, append axes_class parameter.

import matplotlib.axes as maxes
cax = divider.new_horizontal(size="5%", pad=0.05, axes_class=maxes.Axes)

Then your code should work.

Just in case, with the axes_grid's own Axes class, instead of looping
over major_ticks, you do

cax.axis["left"].toggle(all=False)
cax.axis["right"].toggle(all=True)

Regards,

-JJ

···

On Fri, Mar 5, 2010 at 9:38 AM, Thomas Robitaille <thomas.robitaille@...287...> wrote:

Hi Jae-Joon,

I am encountering another issue, when using the method you suggest in combination with the parasite_axes from the matplotlib toolkit:

---

import matplotlib.pyplot as mpl
import numpy as np
from mpl_toolkits.axes_grid import make_axes_locatable
import mpl_toolkits.axes_grid.parasite_axes as mpltk

fig = mpl.figure()

ax = mpltk.SubplotHost(fig, 1, 1, 1)
fig.add_axes(ax)

divider = make_axes_locatable(ax)

cax = divider.new_horizontal(size="5%", pad=0.05)
fig.add_axes(cax)

image = ax.imshow(np.random.random((100,100)))

cb = fig.colorbar(image, cax=cax)

---

In the above case, the labels end up on the wrong side of the plot, and the usual method for changing the label position, e.g.:

for tick in cax.xaxis.get_major_ticks():
tick.tick1On = True
tick.tick2On = True
tick.label1On = False
tick.label2On = True

does not work. Do you have any idea why this might be?

Thanks for any help,

Thomas

On Mar 4, 2010, at 10:28 PM, Jae-Joon Lee wrote:

see

Re: [Matplotlib-users] Transform problem with fixed aspect ratio

axes_grid toolkit provides some helper function that utilizes
axes_locator (take a look at demo_locatable_axes_easy function in the
example below)

http://matplotlib.sourceforge.net/examples/axes_grid/demo_axes_divider.html

-JJ

On Thu, Mar 4, 2010 at 9:05 PM, Thomas Robitaille >> <thomas.robitaille@...287...> wrote:

Hi,

I am trying to set up a colorbar that automatically resizes if I zoom in to an image (which changes the aspect ratio of the axes, so I want the colorbar to get resized too). Let's say I have two Axes instances, say ax (for the main image) and cax (for the colorbar). I can set up a callback if the view limits in one axes change, for example

ax.callbacks.connect('xlim_changed', update_colorbar)
ax.callbacks.connect('ylim_changed', update_colorbar)

Now I can store a reference to cax inside ax:

ax._cax = cax

And I can now define update_colorbar so that it basically changes the position of cax:

def update_colorbar(ax):

# Get current position
xmin = ax..get_position().xmin
...

# Compute new colorbar position
...

# Set new position
ax._cax.set_position(...)

# Return axes instance
return ax

Now the issue is that if I select a region of the image to zoom into, then as soon as I've selected the region, update_colorbar gets called, but by then, the aspect ratio of ax hasn't changed, and so the position I find when I do xmin = ax..get_position().xmin in update_colorbar is the *old* position of ax, not the new one. So the colorbar position is always one step behind compared to the main image axes.

Can anyone think of any way that would avoid this issue, and to be able to use the *new* position of ax inside update_colorbar?

Thanks in advance for any help,

Thomas
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Hi Jae-Joon,

Thanks for your help! One last question - if I create a colorbar axes with

cax = divider.new_horizontal(size="5%", pad=0.05)

Is it possible to then modify the size and pad parameters, or do I need to delete the axes and start again?

Cheers,

Tom

···

On Mar 5, 2010, at 12:20 PM, Jae-Joon Lee wrote:

Unfortunately, axes_grid toolkit (in most cases) creates an axes using
its own Axes class by default. Here is some more details.

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

To use mpl's original Axes class, append axes_class parameter.

import matplotlib.axes as maxes
cax = divider.new_horizontal(size="5%", pad=0.05, axes_class=maxes.Axes)

Then your code should work.

Just in case, with the axes_grid's own Axes class, instead of looping
over major_ticks, you do

cax.axis["left"].toggle(all=False)
cax.axis["right"].toggle(all=True)

Regards,

-JJ

On Fri, Mar 5, 2010 at 9:38 AM, Thomas Robitaille > <thomas.robitaille@...287...> wrote:

Hi Jae-Joon,

I am encountering another issue, when using the method you suggest in combination with the parasite_axes from the matplotlib toolkit:

---

import matplotlib.pyplot as mpl
import numpy as np
from mpl_toolkits.axes_grid import make_axes_locatable
import mpl_toolkits.axes_grid.parasite_axes as mpltk

fig = mpl.figure()

ax = mpltk.SubplotHost(fig, 1, 1, 1)
fig.add_axes(ax)

divider = make_axes_locatable(ax)

cax = divider.new_horizontal(size="5%", pad=0.05)
fig.add_axes(cax)

image = ax.imshow(np.random.random((100,100)))

cb = fig.colorbar(image, cax=cax)

---

In the above case, the labels end up on the wrong side of the plot, and the usual method for changing the label position, e.g.:

for tick in cax.xaxis.get_major_ticks():
tick.tick1On = True
tick.tick2On = True
tick.label1On = False
tick.label2On = True

does not work. Do you have any idea why this might be?

Thanks for any help,

Thomas

On Mar 4, 2010, at 10:28 PM, Jae-Joon Lee wrote:

see

Re: [Matplotlib-users] Transform problem with fixed aspect ratio

axes_grid toolkit provides some helper function that utilizes
axes_locator (take a look at demo_locatable_axes_easy function in the
example below)

http://matplotlib.sourceforge.net/examples/axes_grid/demo_axes_divider.html

-JJ

On Thu, Mar 4, 2010 at 9:05 PM, Thomas Robitaille >>> <thomas.robitaille@...287...> wrote:

Hi,

I am trying to set up a colorbar that automatically resizes if I zoom in to an image (which changes the aspect ratio of the axes, so I want the colorbar to get resized too). Let's say I have two Axes instances, say ax (for the main image) and cax (for the colorbar). I can set up a callback if the view limits in one axes change, for example

ax.callbacks.connect('xlim_changed', update_colorbar)
ax.callbacks.connect('ylim_changed', update_colorbar)

Now I can store a reference to cax inside ax:

ax._cax = cax

And I can now define update_colorbar so that it basically changes the position of cax:

def update_colorbar(ax):

   # Get current position
   xmin = ax..get_position().xmin
   ...

   # Compute new colorbar position
   ...

   # Set new position
   ax._cax.set_position(...)

   # Return axes instance
   return ax

Now the issue is that if I select a region of the image to zoom into, then as soon as I've selected the region, update_colorbar gets called, but by then, the aspect ratio of ax hasn't changed, and so the position I find when I do xmin = ax..get_position().xmin in update_colorbar is the *old* position of ax, not the new one. So the colorbar position is always one step behind compared to the main image axes.

Can anyone think of any way that would avoid this issue, and to be able to use the *new* position of ax inside update_colorbar?

Thanks in advance for any help,

Thomas
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

divider.get_horizontal() returns a list of size objects
(http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/api/axes_size_api.html#module-mpl_toolkits.axes_grid.axes_size)
that are currently used.

For example,

  cax = divider.new_horizontal(size="5%", pad=0.05)
  horiz_list = divider.get_horizontal()

horiz_list[0] is x-size of ax, horiz_list[1] is pad size, and
horiz_list[2] is x-size of cax. You can modify those size objects (but
usually they don't provide public interfaces). Or you can substitute
any of them with a valid size object.

  horiz_list[1]._fixed_size = 0. # makes pad 0 inches
  horiz_list[2]._fraction = 0.1 # width of cax becomes 10% of the width of ax

Or

  from mpl_toolkits.axes_grid.axes_size import Fixed, Fraction
  horiz_list[1] = Fixed(0.)
  horiz_list[2] = Fraction(0.1, horiz_list[0])

There are not much of documentation available, but this may be helpful.

http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/users/axes_divider.html

Regards,

-JJ

···

On Fri, Mar 5, 2010 at 3:38 PM, Thomas Robitaille <thomas.robitaille@...287...> wrote:

Hi Jae-Joon,

Thanks for your help! One last question - if I create a colorbar axes with

cax = divider.new_horizontal(size="5%", pad=0.05)

Is it possible to then modify the size and pad parameters, or do I need to delete the axes and start again?

Cheers,

Tom

On Mar 5, 2010, at 12:20 PM, Jae-Joon Lee wrote:

Unfortunately, axes_grid toolkit (in most cases) creates an axes using
its own Axes class by default. Here is some more details.

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

To use mpl's original Axes class, append axes_class parameter.

import matplotlib.axes as maxes
cax = divider.new_horizontal(size="5%", pad=0.05, axes_class=maxes.Axes)

Then your code should work.

Just in case, with the axes_grid's own Axes class, instead of looping
over major_ticks, you do

cax.axis["left"].toggle(all=False)
cax.axis["right"].toggle(all=True)

Regards,

-JJ

On Fri, Mar 5, 2010 at 9:38 AM, Thomas Robitaille >> <thomas.robitaille@...287...> wrote:

Hi Jae-Joon,

I am encountering another issue, when using the method you suggest in combination with the parasite_axes from the matplotlib toolkit:

---

import matplotlib.pyplot as mpl
import numpy as np
from mpl_toolkits.axes_grid import make_axes_locatable
import mpl_toolkits.axes_grid.parasite_axes as mpltk

fig = mpl.figure()

ax = mpltk.SubplotHost(fig, 1, 1, 1)
fig.add_axes(ax)

divider = make_axes_locatable(ax)

cax = divider.new_horizontal(size="5%", pad=0.05)
fig.add_axes(cax)

image = ax.imshow(np.random.random((100,100)))

cb = fig.colorbar(image, cax=cax)

---

In the above case, the labels end up on the wrong side of the plot, and the usual method for changing the label position, e.g.:

for tick in cax.xaxis.get_major_ticks():
tick.tick1On = True
tick.tick2On = True
tick.label1On = False
tick.label2On = True

does not work. Do you have any idea why this might be?

Thanks for any help,

Thomas

On Mar 4, 2010, at 10:28 PM, Jae-Joon Lee wrote:

see

Re: [Matplotlib-users] Transform problem with fixed aspect ratio

axes_grid toolkit provides some helper function that utilizes
axes_locator (take a look at demo_locatable_axes_easy function in the
example below)

http://matplotlib.sourceforge.net/examples/axes_grid/demo_axes_divider.html

-JJ

On Thu, Mar 4, 2010 at 9:05 PM, Thomas Robitaille >>>> <thomas.robitaille@...287...> wrote:

Hi,

I am trying to set up a colorbar that automatically resizes if I zoom in to an image (which changes the aspect ratio of the axes, so I want the colorbar to get resized too). Let's say I have two Axes instances, say ax (for the main image) and cax (for the colorbar). I can set up a callback if the view limits in one axes change, for example

ax.callbacks.connect('xlim_changed', update_colorbar)
ax.callbacks.connect('ylim_changed', update_colorbar)

Now I can store a reference to cax inside ax:

ax._cax = cax

And I can now define update_colorbar so that it basically changes the position of cax:

def update_colorbar(ax):

# Get current position
xmin = ax..get_position().xmin
...

# Compute new colorbar position
...

# Set new position
ax._cax.set_position(...)

# Return axes instance
return ax

Now the issue is that if I select a region of the image to zoom into, then as soon as I've selected the region, update_colorbar gets called, but by then, the aspect ratio of ax hasn't changed, and so the position I find when I do xmin = ax..get_position().xmin in update_colorbar is the *old* position of ax, not the new one. So the colorbar position is always one step behind compared to the main image axes.

Can anyone think of any way that would avoid this issue, and to be able to use the *new* position of ax inside update_colorbar?

Thanks in advance for any help,

Thomas
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options