matplotlib: overlay plots with different scales?

It sounds like what you’re wanting is subplots… What you’re doing now doesn’t make much sense (Or I’m very confused by your code snippet, at any rate…).

Try something more like this:

import matplotlib.pyplot as plt
import numpy as np

fig, axes = plt.subplots(nrows=3)

colors = ('k', 'r', 'b')
for ax, color in zip(axes, colors):
    data = np.random.random(1) * np.random.random(10)
    ax.plot(data, marker="o", linestyle="none", color=color)

plt.show()

enter image description here

Edit:

If you don’t want subplots, your code snippet makes a lot more sense.

You’re trying to add three axes right on top of each other. Matplotlib is recognizing that there’s already a subplot in that exactly size and location on the figure, and so it’s returning the same axes object each time. In other words, if you look at your list ax, you’ll see that they’re all the same object.

If you really want to do that, you’ll need to reset fig._seen to an empty dict each time you add an axes. You probably don’t really want to do that, however.

Instead of putting three independent plots over each other, have a look at using twinx instead.

E.g.

import matplotlib.pyplot as plt
import numpy as np
# To make things reproducible...
np.random.seed(1977)

fig, ax = plt.subplots()

# Twin the x-axis twice to make independent y-axes.
axes = [ax, ax.twinx(), ax.twinx()]

# Make some space on the right side for the extra y-axis.
fig.subplots_adjust(right=0.75)

# Move the last y-axis spine over to the right by 20% of the width of the axes
axes[-1].spines['right'].set_position(('axes', 1.2))

# To make the border of the right-most axis visible, we need to turn the frame
# on. This hides the other plots, however, so we need to turn its fill off.
axes[-1].set_frame_on(True)
axes[-1].patch.set_visible(False)

# And finally we get to plot things...
colors = ('Green', 'Red', 'Blue')
for ax, color in zip(axes, colors):
    data = np.random.random(1) * np.random.random(10)
    ax.plot(data, marker="o", linestyle="none", color=color)
    ax.set_ylabel('%s Thing' % color, color=color)
    ax.tick_params(axis="y", colors=color)
axes[0].set_xlabel('X-axis')

plt.show()

enter image description here

Leave a Comment