Create a second y-axis in matplotlib

Today I was trying to figure out how to plot two time series with differently scaled values. I found two_scales.py example in the matplotlib examples which describes how to do it.

Here’s a slightly simplified version of the code, and afterward a detailed explanation of what’s going on.


from pylab import *

x = [1,2,3,4,5]
y1 = [10,25,30,45,50]
y2 = [1,3,4,7,12]

ax1 = subplot(111)

plot(x, y1, 'b-')

ax2 = twinx()

plot(x, y2, 'r--')
show()

Step-by-step explanation.

Basically, we make two separate axes right on top of each other. The data in y1 will go on the first created axes, and y2 will go on the second created axes. The key to this is the twinx() function. What it does is explained below.
two axes code explanation 01


two axes code explanation 03


two axes code explanation 04
What’s happening here? twinx() duplicates the current set of axes (the current set of axes is ax1). The source code of twinx() has a line like this:

ax2 = gcf().add_axes(ax1.get_position(), sharex=ax1, frameon=False)

Which:

  • adds a new set of axes to the current figure (that’s the gcf() part).
  • puts the new set of axes in the same position as ax1 (that’s the ax1.get_position() part)
  • makes the new set of axes have an x axis with the same properties as the first axes, ax1. When you pan or zoom the figure both axes will move together.
  • returns the new axis

The result is a new set of axes right on top of the old one, ready and primed for some plotting.

The rest of the code plots a red dashed line in the new axes using the data in y2, and the show() command shows your handiwork.
*not really magic

Final product

two y axes example

Oh no! I forgot to label the axes!

The nice thing about saving the axes as ax1 and ax2 is that you can change either one of them at any time. Just call any one of the 280 possibilities (In IPython, type ax1, then a “.”, then the tab key — that is, ax1.[TAB] — for a list of what axes can do).

For example, you can use the set_ylabel() method of each axes object.


ax1.set_ylabel('first y-axis')
ax2.set_yabel('second y-axis')

If you have already used show(), then your changes WON’T immediately be updated. This is by design, in case you are adding many things to a figure and don’t want to refresh after every little thing you add. Once you’re ready to redraw the figure, Use

draw()

You can label the x axis too, but you’ll only need to choose either ax1.set_xlabel(‘x label here’) or ax2.set_xlabel(‘x label here’). You can remove an axis label by just setting it to an empty string: ax2.set_xlabel(”).

With labels, it looks something like this:
two y axes with axis labels

More than two y-axes?

Unfortunately, this is not yet implemented in matplotlib but it’s on the wishlist, as this post describes, along with a suggestion to use PyX instead of matplotlib for a graph of this type.

0 Responses to “Create a second y-axis in matplotlib”


  • No Comments

Leave a Reply