Question

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?

Was it helpful?

Solution

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([])

OTHER TIPS

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

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top