Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

## matplotlib-users

 [Matplotlib-users] more than two y-axes From: Thomas Tanner - 2008-01-31 14:05:17 Hi, I'd like to have figure with 3 (or 4) plots having different scales but sharing the same x-axis. Basically I want an extension of the twinx command (see, e.g, two_scales.py demo). I'm using 0.91.2svn on MacOSX10.5.1 from http://trichech.us/?page_id=3D5 I've tried the following hack (creating very narrow axes for the 3rd y-axis), which seems to work reasonably well but leads to a thick tick=20 line. As expected pan&zoom doesn't work for all axes. ------------------------------------------------------------------- #!/usr/bin/env python from pylab import * # some functions to plot x=3Dlinspace(0,2*pi,100) y1=3Dsin(x) y2=3D10*cos(x) y3=3D0.5*cos(2*x) # create main axes factor=3D0.9 # how much x-space is used by subaxes am=3Daxes(xticks=3D[]) pos =3D am.get_position() pos[2] =3D factor*pos[2] # frame for subaxes # first plot a1=3Daxes(pos,frameon=3DTrue) p1=3Dplot(x,y1,'b') xlim(min(x),max(x)) xlabel("x") a1.yaxis.tick_left() ylabel("axis 1") # second plot, y-axis on the right side a2=3Daxes(pos,frameon=3DFalse) p2=3Dplot(x,y2,'r') xlim(a1.get_xlim()) a2.yaxis.tick_right() a2.yaxis.set_label_position("right") ylabel("axis 2") # third plot, 2nd y-axis on the right side taken over by main axes a3=3Daxes(pos,frameon=3DFalse,yticks=3D[],xticks=3D[]) p3=3Dplot(x,y3,'g') xlim(min(x),max(x)) # legend for all three plots legend((p1,p2,p3),('plot 1','plot 2','plot 3'),loc=3D0) # now adjust settings for main axes # draw y-axis of third plot axes(am) pos =3D am.get_position() # move to right and make it a line pos[0] +=3D pos[2] pos[2] =3D 0.001 # 0 doesn't work am.set_position(pos) # draw third y-axis ylim(a3.get_ylim()) ylabel("axis 3") am.yaxis.tick_right() am.yaxis.set_label_position("right") show() ------------------------------------------------------------------- However, if I try to extend it to 4 y-axes (2 on each side) I encounter several problems: ------------------------------------------------------------------- #!/usr/bin/env python from pylab import * # some functions to plot x=3Dlinspace(0,2*pi,100) y1=3Dsin(x) y2=3D10*cos(x) y3=3D0.5*cos(2*x) y4=3D2*sin(0.5*x) # create main axes factor=3D0.1 # how much x-space is used by y-axes am=3Daxes(xticks=3D[]) pos =3D am.get_position() # frame for subaxes pos[0] +=3D factor*pos[2] pos[2] =3D (1-2*factor)*pos[2] # frame for subaxes # first plot, 2nd y-axis on the left side taken over by main axes a1=3Daxes(pos,frameon=3DFalse,yticks=3D[],xticks=3D[]) p1=3Dplot(x,y1,'b') xlim(min(x),max(x)) ylim1=3D a1.get_ylim() # bug: save as it is overwritten by plot4 # second plot, axis left a2=3Daxes(pos,frameon=3DTrue) p2=3Dplot(x,y2,'r') xlim(a1.get_xlim()) xlabel("x") a2.yaxis.tick_left() ylabel("axis 2") # third plot, y-axis on the right side a3=3Daxes(pos,frameon=3DFalse) p3=3Dplot(x,y3,'g') xlim(a1.get_xlim()) a3.yaxis.tick_right() a3.yaxis.set_label_position("right") ylabel("axis 3") # fourth plot, 2nd y-axis on the right side taken over by main axes a4=3Daxes(pos,frameon=3DFalse,yticks=3D[],xticks=3D[]) p4=3Dplot(x,y4,'m') xlim(a1.get_xlim()) ylim4 =3D a4.get_ylim() # legend for all three plots legend((p1,p2,p3,p4),('plot 1','plot 2','plot 3','plot 4')) # now adjust settings for main axes # draw y-axis of third plot axes(am) pos =3D am.get_position() pos2 =3D array(pos) pos[2] =3D 0.001 am.set_position(pos) # draw third y-axis am.set_ylim(ylim1) a1.set_ylim(ylim1) am.add_artist(a1) ylabel("axis 1") am.yaxis.tick_left() am.yaxis.set_label_position("left") # now adjust settings for main axes # draw y-axis of fourth plot # move to right and make it a line pos2[0] +=3D pos2[2] pos2[2] =3D 0.001 am2 =3D axes(pos2,xticks=3D[]) # draw fourth y-axis am2.set_ylim(ylim4) a4.set_ylim(ylim4) am2.add_artist(a4) ylabel("axis 4") am2.yaxis.tick_right() am2.yaxis.set_label_position("right") show() ------------------------------------------------------------------- The 4th plot overwrites the ylim of the 1st plot (bug?). Is there a limit of 3 axes per figure? The ylim of plot4 is still ignored. Why do I have to add the axes a1 and a4 the main axes to make them visibl= e? Any ideas? cheers, --=20 Thomas Tanner ---------------- email: tanner@... phone: (+49) 7071 601 608 GnuPG key id: 1024/5924D4DD Max Planck Institute for Biological Cybernetics Spemannstrasse 38 72076 T=FCbingen, Germany
 Re: [Matplotlib-users] more than two y-axes From: Anthony Floyd - 2008-02-02 01:12:27 On Jan 31, 2008 6:03 AM, Thomas Tanner wrote: > Hi, > I'd like to have figure with 3 (or 4) plots having different scales > but sharing the same x-axis. > Basically I want an extension of the twinx command (see, e.g, > two_scales.py demo). > I'm using 0.91.2svn on MacOSX10.5.1 from http://trichech.us/?page_id=5 [snip] > The 4th plot overwrites the ylim of the 1st plot (bug?). > Is there a limit of 3 axes per figure? > The ylim of plot4 is still ignored. > Why do I have to add the axes a1 and a4 the main axes to make them visible? I'm working on an app that has 8 axes per figure (X1, X2, Y1 ... Y4) and it works fine. Well, the MPL bits do. One of the unexpected things that we had to do in order to get the multiple plots to work as expected was to ensure that each additional subplot had its own label. MPL has some 'helper' code that tries to consolidate the axes so that if you create two axes with identical parameters, you only end up with one axes object (I think -- someone more knowledgeable can fill you in on the details). Now, we do things using the API rather than using pylab, some I'm not entirely certain (and haven't tested it) but I think that the pylab command 'axes' has an optional argument of 'label', which you should set to be a unique string for each subplot. I've only scanned through your code, and I'm not at all familiar with the pylab syntax, but I'm puzzled that you haven't used twinx (or in API parlance, sharex) anywhere. Regardless, the API code for overlaying subplots is of the form: figure.add_axes(axes1.get_position(), sharex=axes1, frameon=False, label='someUniqueString') Hope this helps, Anthony.