one data set, two y axis scales

Hi everyone,

Suppose I have the following data set

···

-----------------------------
Time Temperature (F)
1 78
2 79
3 79
4 77
-----------------------------

I want to make a plot with both y axes labeled. The one on the left (y1)
will be in Fahrenheit, while the one on the right (y2) in Celsius. Is there
a way to do this?

Thank you.

--
View this message in context: http://www.nabble.com/one-data-set%2C-two-y-axis-scales-tp23863680p23863680.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

Hi,

···

On Thu, Jun 4, 2009 at 06:56, musik <xi.xiaoxiang@...287...> wrote:

I want to make a plot with both y axes labeled. The one on the left (y1)
will be in Fahrenheit, while the one on the right (y2) in Celsius. Is there
a way to do this?

what you're looking for is [1]

[1] http://matplotlib.sourceforge.net/api/pyplot_api.html?highlight=twinx#matplotlib.pyplot.twinx

Cheers,
--
Sandro Tosi (aka morph, morpheus, matrixhasu)
My website: http://matrixhasu.altervista.org/
Me at Debian: http://wiki.debian.org/SandroTosi

Well you can make it work that way, but I think what the original poster wants is just to plot the data once, with one set of units on the left and another on the right. Using twinx would make two identical lines just to make two different scales. It seems to me that there should be an easier way, but I’m not sure that one exists…

Ryan

···

On Thu, Jun 4, 2009 at 6:01 AM, Sandro Tosi <matrixhasu@…1972…> wrote:

Hi,

On Thu, Jun 4, 2009 at 06:56, musik <xi.xiaoxiang@…287…> wrote:

I want to make a plot with both y axes labeled. The one on the left (y1)

will be in Fahrenheit, while the one on the right (y2) in Celsius. Is there

a way to do this?

what you’re looking for is [1]

[1] http://matplotlib.sourceforge.net/api/pyplot_api.html?highlight=twinx#matplotlib.pyplot.twinx


Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma
Sent from Norman, Oklahoma, United States

Exactly. I want to plot the original data once, but the two y axes show
different scales (units). Is twinx() good for that? How?

Thanks.

Ryan May-3 wrote:

···

On Thu, Jun 4, 2009 at 6:01 AM, Sandro Tosi <matrixhasu@...287...> wrote:

Hi,

On Thu, Jun 4, 2009 at 06:56, musik <xi.xiaoxiang@...287...> wrote:
> I want to make a plot with both y axes labeled. The one on the left
(y1)
> will be in Fahrenheit, while the one on the right (y2) in Celsius. Is
there
> a way to do this?

what you're looking for is [1]

[1]
http://matplotlib.sourceforge.net/api/pyplot_api.html?highlight=twinx#matplotlib.pyplot.twinx

Well you can make it work that way, but I think what the original poster
wants is just to plot the data once, with one set of units on the left and
another on the right. Using twinx would make two identical lines just to
make two different scales. It seems to me that there *should* be an
easier
way, but I'm not sure that one exists...

Ryan

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma
Sent from Norman, Oklahoma, United States

------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises
looking to deploy the next generation of Solaris that includes the latest
innovations from Sun and the OpenSource community. Download a copy and
enjoy capabilities such as Networking, Storage and Virtualization.
Go to: http://p.sf.net/sfu/opensolaris-get
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

--
View this message in context: http://www.nabble.com/one-data-set%2C-two-y-axis-scales-tp23863680p23871873.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

I wouldn’t call it “good”, but you can make it work. Basically, you’d plot your data once in F, then convert it to C and plot it a second time.

Ryan

···

On Thu, Jun 4, 2009 at 10:08 AM, musik <xi.xiaoxiang@…985…> wrote:

Exactly. I want to plot the original data once, but the two y axes show

different scales (units). Is twinx() good for that? How?

Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma
Sent from Norman, Oklahoma, United States

I hope the code below gives you some idea.

def Tc(Tf): return (5./9.)*(Tf-32)

ax1 = subplot(111) # y-axis in F
ax2 = twinx() # y-axis in C

def update_ax2(ax1):
    y1, y2 = ax1.get_ylim()
    ax2.set_ylim(Tc(y1), Tc(y2))

# automatically update ylim of ax2 when ylim of ax1 changes.
ax1.callbacks.connect("ylim_changed", update_ax2)
ax1.plot([78, 79, 79, 77])

-JJ

···

On Thu, Jun 4, 2009 at 11:08 AM, musik <xi.xiaoxiang@...287...> wrote:

Exactly. I want to plot the original data once, but the two y axes show
different scales (units). Is twinx() good for that? How?

Thanks.

Ryan May-3 wrote:

On Thu, Jun 4, 2009 at 6:01 AM, Sandro Tosi <matrixhasu@...287...> wrote:

Hi,

On Thu, Jun 4, 2009 at 06:56, musik <xi.xiaoxiang@...287...> wrote:
> I want to make a plot with both y axes labeled. The one on the left
(y1)
> will be in Fahrenheit, while the one on the right (y2) in Celsius. Is
there
> a way to do this?

what you're looking for is [1]

[1]
http://matplotlib.sourceforge.net/api/pyplot_api.html?highlight=twinx#matplotlib.pyplot.twinx

Well you can make it work that way, but I think what the original poster
wants is just to plot the data once, with one set of units on the left and
another on the right. Using twinx would make two identical lines just to
make two different scales. It seems to me that there *should* be an
easier
way, but I'm not sure that one exists...

Ryan

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma
Sent from Norman, Oklahoma, United States

------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises
looking to deploy the next generation of Solaris that includes the latest
innovations from Sun and the OpenSource community. Download a copy and
enjoy capabilities such as Networking, Storage and Virtualization.
Go to: http://p.sf.net/sfu/opensolaris-get
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

--
View this message in context: http://www.nabble.com/one-data-set%2C-two-y-axis-scales-tp23863680p23871873.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises
looking to deploy the next generation of Solaris that includes the latest
innovations from Sun and the OpenSource community. Download a copy and
enjoy capabilities such as Networking, Storage and Virtualization.
Go to: http://p.sf.net/sfu/opensolaris-get
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Well I know I just learned something…

Ryan

···

On Thu, Jun 4, 2009 at 12:16 PM, Jae-Joon Lee <lee.j.joon@…2015…87…> wrote:

I hope the code below gives you some idea.

def Tc(Tf): return (5./9.)*(Tf-32)

ax1 = subplot(111) # y-axis in F

ax2 = twinx() # y-axis in C

def update_ax2(ax1):

y1, y2 = ax1.get_ylim()

ax2.set_ylim(Tc(y1), Tc(y2))

automatically update ylim of ax2 when ylim of ax1 changes.

ax1.callbacks.connect(“ylim_changed”, update_ax2)

ax1.plot([78, 79, 79, 77])


Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Sent from Norman, Oklahoma, United States

This works nicely. Thank you JJ.

Jae-Joon Lee wrote:

···

I hope the code below gives you some idea.

def Tc(Tf): return (5./9.)*(Tf-32)

ax1 = subplot(111) # y-axis in F
ax2 = twinx() # y-axis in C

def update_ax2(ax1):
    y1, y2 = ax1.get_ylim()
    ax2.set_ylim(Tc(y1), Tc(y2))

# automatically update ylim of ax2 when ylim of ax1 changes.
ax1.callbacks.connect("ylim_changed", update_ax2)
ax1.plot([78, 79, 79, 77])

-JJ

On Thu, Jun 4, 2009 at 11:08 AM, musik <xi.xiaoxiang@...287...> wrote:

Exactly. I want to plot the original data once, but the two y axes show
different scales (units). Is twinx() good for that? How?

Thanks.

--
View this message in context: http://www.nabble.com/one-data-set%2C-two-y-axis-scales-tp23863680p23875221.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

Yes, this is a cute little example. I was thinking along the lines
Ryan was, to just plot the same data twice with twinx, but this is
cleverer. I added it to svn as:
examples/api/fahrenheit_celcius_scales.py

But using twinx has always been a hack. I think what we really need
is to have each spine have it's own locator, formatter and tick
collection (eg the natural points for Celcius ticks are different from
the natural points for Fahrenheit ticks) and currently the left and
right ticks of an axis share the axis locator and formatter.
Currently the spines just draw the lines and the axes/axis handle all
the ticks and the locators. It might be more natural to move these
into the spine itself, and support independent
ticks/locators/formatter for each spine, with the default being
shared.

Andrew, did you give this any thought in the spine implementation? I
am pretty sure it would be hard, but maybe you have a better sense of
*how hard*. This would be a nice enhancement.

JDH

···

On Thu, Jun 4, 2009 at 12:16 PM, Jae-Joon Lee<lee.j.joon@...287...> wrote:

I hope the code below gives you some idea.

def Tc(Tf): return (5./9.)*(Tf-32)

ax1 = subplot(111) # y-axis in F
ax2 = twinx() # y-axis in C

def update_ax2(ax1):
   y1, y2 = ax1.get_ylim()
   ax2.set_ylim(Tc(y1), Tc(y2))

# automatically update ylim of ax2 when ylim of ax1 changes.
ax1.callbacks.connect("ylim_changed", update_ax2)
ax1.plot([78, 79, 79, 77])

John Hunter wrote:

I hope the code below gives you some idea.

def Tc(Tf): return (5./9.)*(Tf-32)

ax1 = subplot(111) # y-axis in F
ax2 = twinx() # y-axis in C

def update_ax2(ax1):
   y1, y2 = ax1.get_ylim()
   ax2.set_ylim(Tc(y1), Tc(y2))

# automatically update ylim of ax2 when ylim of ax1 changes.
ax1.callbacks.connect("ylim_changed", update_ax2)
ax1.plot([78, 79, 79, 77])

Yes, this is a cute little example. I was thinking along the lines
Ryan was, to just plot the same data twice with twinx, but this is
cleverer. I added it to svn as:
examples/api/fahrenheit_celcius_scales.py

But using twinx has always been a hack. I think what we really need
is to have each spine have it's own locator, formatter and tick
collection (eg the natural points for Celcius ticks are different from
the natural points for Fahrenheit ticks) and currently the left and
right ticks of an axis share the axis locator and formatter.
Currently the spines just draw the lines and the axes/axis handle all
the ticks and the locators. It might be more natural to move these
into the spine itself, and support independent
ticks/locators/formatter for each spine, with the default being
shared.

Andrew, did you give this any thought in the spine implementation? I
am pretty sure it would be hard, but maybe you have a better sense of
*how hard*. This would be a nice enhancement.

I think this would be a good direction, as well. It would also allow
disabling the tick mark labels in some axes that share the same axis --
because the ticks/labels would belong to the spine, which itself
wouldn't (necessarily) be shared.

I can't promise anything, but this may be a solution to the issues that
Jae-Joon pointed out w.r.t loglog plots in the spine implementation
(although I suspect they are more general). I'll take a look at it,
although I can't say exactly when I'll do so -- hopefully within the
coming week.

-Andrew

···

On Thu, Jun 4, 2009 at 12:16 PM, Jae-Joon Lee<lee.j.joon@...287...> wrote:

If you go this route, you may want to look at abolishing the Tick
class entirely -- once the ticks are associated with a spine, we will
not need the tick1line, tick2line, label1, label2 instances. We can
draw all the ticks along a given spine with a single Line2D object
using the marker styles TICKLEFT, TICKRIGHT, TICKUP, and TICKDOWN. We
really do not need heterogeneous properties along a given spine, so we
are paying a lot to have separate artist instances for each of these
things. The tick labels will be a little harder since Text is so
complicated, so you might want to punt at the outset and just have the
spine hold a list of Text instances, and down the road we can think
about a more efficient text collection if necessary.

Thinking out loud.... But for nonlinear coordinate systems, where
ticks may be oriented in different directions, the single Line2D idea
may not work so tread cautiously -- perhaps a line collection for the
tick lines....

I am willing to have some breakage in support of this, though we can
try to make the top level axes methods accessor (e get_xticklabels)
do the intuitive thing.

JDH

···

On Fri, Jun 5, 2009 at 11:44 AM, Andrew Straw<strawman@...106...> wrote:

I think this would be a good direction, as well. It would also allow
disabling the tick mark labels in some axes that share the same axis --
because the ticks/labels would belong to the spine, which itself
wouldn't (necessarily) be shared.

I can't promise anything, but this may be a solution to the issues that
Jae-Joon pointed out w.r.t loglog plots in the spine implementation
(although I suspect they are more general). I'll take a look at it,
although I can't say exactly when I'll do so -- hopefully within the
coming week.

John,

These ideas have been part of motivation behind my axes_grid toolkit.
In the module documentation of
"lib/mpl_toolkits/axes_grid/axislines.py", I tried to briefly explain
what I wanted and what I implemented, although the explanation is very
far from complete (also some examples are found in
http://matplotlib.sourceforge.net/mpl_toolkits/axes_grid/users/overview.html#axisline
). Note that my ultimate goal was to support the curvelinear
coordinate system, as demonstrated in my recent example
(examples/axes_grid/demo_curvelinear_grid.py).

And my hope is that, if we're going to this direction and somehow
expand the "spines" to support these ideas, please make it possible to
customize and expand although only the basic features are supported by
the vanilla mpl. For example, in curvelinear coordinate, ticks can
have arbitrary angles, so I hope that the tickstyles are not strictly
limited to [TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN] by design. It would
be great if there is a chance to discuss about the overall design
before implementing something in this regard.

My current implementation in axes_grid toolkit became rather
complicated, and some of them are implemented in quick and dirty ways.
However, I guess it would be helpful to go over how thing are
currently implemented in axes_grid toolkit and further discuss how
we're going to do this within the mpl. I'll try to write up short
documentation about my design during this weekend.

Regards,

-JJ

···

On Fri, Jun 5, 2009 at 1:07 PM, John Hunter<jdh2358@...287...> wrote:

On Fri, Jun 5, 2009 at 11:44 AM, Andrew Straw<strawman@...106...> wrote:

I think this would be a good direction, as well. It would also allow
disabling the tick mark labels in some axes that share the same axis --
because the ticks/labels would belong to the spine, which itself
wouldn't (necessarily) be shared.

I can't promise anything, but this may be a solution to the issues that
Jae-Joon pointed out w.r.t loglog plots in the spine implementation
(although I suspect they are more general). I'll take a look at it,
although I can't say exactly when I'll do so -- hopefully within the
coming week.

If you go this route, you may want to look at abolishing the Tick
class entirely -- once the ticks are associated with a spine, we will
not need the tick1line, tick2line, label1, label2 instances. We can
draw all the ticks along a given spine with a single Line2D object
using the marker styles TICKLEFT, TICKRIGHT, TICKUP, and TICKDOWN. We
really do not need heterogeneous properties along a given spine, so we
are paying a lot to have separate artist instances for each of these
things. The tick labels will be a little harder since Text is so
complicated, so you might want to punt at the outset and just have the
spine hold a list of Text instances, and down the road we can think
about a more efficient text collection if necessary.

Thinking out loud.... But for nonlinear coordinate systems, where
ticks may be oriented in different directions, the single Line2D idea
may not work so tread cautiously -- perhaps a line collection for the
tick lines....

I am willing to have some breakage in support of this, though we can
try to make the top level axes methods accessor (e get_xticklabels)
do the intuitive thing.

JDH

Jae-Joon Lee wrote:

...
def Tc(Tf): return (5./9.)*(Tf-32)

ax1 = subplot(111) # y-axis in F
ax2 = twinx() # y-axis in C

def update_ax2(ax1):
    y1, y2 = ax1.get_ylim()
    ax2.set_ylim(Tc(y1), Tc(y2))

# automatically update ylim of ax2 when ylim of ax1 changes.
ax1.callbacks.connect("ylim_changed", update_ax2)
ax1.plot([78, 79, 79, 77])
...

Thanks, this was also useful for me. I see that you are discussing
shortcomings of twinx -- so perhaps the following is one of those...

I was using this exact script with an additional

ax1.set_yscale('log')
ax2.set_yscale('log')

and the ticks seem to be messed up. I used 'ipython -pylab' with
matplotlib.__version__ '0.98.3'.

Is there something I can do to get the ticks only at the places i would
like them to be?

Thanks,
Sebastian.