user3562
user3562

Reputation: 587

Multiple overlapping plots with independent scaling in Matplotlib

I currently have code that calls matplotlib.pylab.plot multiple times to display multiple sets of data on the same screen, and Matplotlib scales each to the global min and max, considering all plots. Is there a way to ask it to scale each plot independently, to the min and max of that particular plot?

Upvotes: 9

Views: 12052

Answers (4)

radtek
radtek

Reputation: 36270

Here is a solution using date plots, and I think its the most optimized solution using twinx() a short hand for adding a second y axis.

import matplotlib.pyplot as plt
import matplotlib.dates as md
import datetime
import numpy
numpy.random.seed(0)
t = md.drange(datetime.datetime(2012, 11, 1),
            datetime.datetime(2014, 4, 01),
            datetime.timedelta(hours=1))  # takes start, end, delta
x1 = numpy.cumsum(numpy.random.random(len(t)) - 0.5) * 40000
x2 = numpy.cumsum(numpy.random.random(len(t)) - 0.5) * 0.002
fig = plt.figure()
ax1 = fig.add_subplot(111)
fig.suptitle('a title', fontsize=14)
fig.autofmt_xdate()
plt.ylabel('axis 1')
plt.xlabel('dates')
ax2 = ax1.twinx()
ax1.plot_date(t, x1, 'b-', alpha=.65)
ax2.plot_date(t, x2, 'r-', alpha=.65)
plt.ylabel('axis 2')
plt.show()

From the docs, matplotlib.pyplot.twinx(ax=None) Make a second axes that shares the x-axis. The new axes will overlay ax (or the current axes if ax is None). The ticks for ax2 will be placed on the right, and the ax2 instance is returned. More here.

Upvotes: 0

radtek
radtek

Reputation: 36270

I need something like this but wanted to create an example that you can copy and paste into the interactive shell and take a look at it. Here it is for those of you requiring a working solution:

from numpy import arange
from math import sin, cos
import matplotlib.pyplot as plt

x = arange(10)
y1 = [sin(i) for i in x]
y2 = [10*cos(i) for i in x]

rect = [0.1, 0.1, 0.8, 0.8]
a1 = plt.axes(rect)  # Create subplot, rect = [left, bottom, width, height] in normalized (0, 1) units
a1.yaxis.tick_left()  # Use ticks only on left side of plot
plt.plot(x, y1)
plt.ylabel('axis 1')
plt.xlabel('x')

a2 = plt.axes(rect, frameon=False)  # frameon, if False, suppress drawing the figure frame
a2.yaxis.tick_right()
plt.plot(x, y2)
a2.yaxis.set_label_position('right')
plt.ylabel('axis 2')
a2.set_xticks([])

plt.show()

Tested and works in python 2.7.6, numpy 1.8.1, matpotlib 1.3.1. I'm going to continue playing with it, looking for a neat way to work with overlaying date plots. I'll post back my findings.

Upvotes: 0

dmorlock
dmorlock

Reputation: 2021

This is how you create a single plot (add_subplot(1,1,1)) and limit the scale on the y-axes.

myFig = figure()
myPlot = self.figure.add_subplot(1,1,1)
myPlot.plot([1,2,3,4,5], [5,4,3,2,1], '+r')
myPlot.set_ylim(1,5) # Limit y-axes min 1, max 5

Upvotes: 0

Jouni K. Seppänen
Jouni K. Seppänen

Reputation: 44118

There's no direct support for this, but here's some code from a mailing list posting that illlustrates two independent vertical axes:

x=arange(10)
y1=sin(x)
y2=10*cos(x)

rect=[0.1,0.1,0.8,0.8]
a1=axes(rect)
a1.yaxis.tick_left()
plot(x,y1)
ylabel('axis 1')
xlabel('x')

a2=axes(rect,frameon=False)
a2.yaxis.tick_right()
plot(x,y2)
a2.yaxis.set_label_position('right')
ylabel('axis 2')
a2.set_xticks([])

Upvotes: 3

Related Questions