From: Alan G Isaac <aisaac@am...>  20040907 01:01:59

I'm a newbie to Matplotlib but a longtime gnuplot user. Using the matlab module, what is the right way to set xzeroaxis (using gnuplot terminology). Using axis and hline seems cumbersome, so I assume there is a better way to implement this common need. Thank you, Alan Isaac 
From: Stephen Walton <stephen.walton@cs...>  20040907 02:26:15
Attachments:
Message as HTML

On Mon, 20040906 at 06:28, Alan G Isaac wrote: > I'm a newbie to Matplotlib but a longtime gnuplot user. > Using the matlab module, what is the right way to > set xzeroaxis MATLAB doesn't have anything similar, AFAIK, but the following will work: def xzeroaxis(form=3D'k'): # draw a line at y=3D0 on the current plot v=3Daxis() plot(v[0:2],[0,0],form) def yzeroaxis(form=3D'k'): v=3Daxis() plot([0,0],v[2:4],form) Is this worth adding to the distribution? I doubt it is general enough to warrant. John: when I do the following: v=3Darange(5,5) plot(v,v**3) xzeroaxis() yzeroaxis() the vertical line at x=3D0 doesn't quite go to top and bottom of the plot. This is with 0.62.4. =20 Stephen Walton <stephen.walton@...> Dept. of Physics & Astronomy, CSU Northridge 
From: John Hunter <jdhunter@ac...>  20040907 03:10:05

>>>>> "Stephen" == Stephen Walton <stephen.walton@...> writes: Stephen> On Mon, 20040906 at 06:28, Alan G Isaac wrote: >> I'm a newbie to Matplotlib but a longtime gnuplot user. Using >> the matlab module, what is the right way to set xzeroaxis Stephen> MATLAB doesn't have anything similar, AFAIK, but the Stephen> following will work: Stephen> def xzeroaxis(form='k'): # draw a line at y=0 on the Stephen> current plot v=axis() plot(v[0:2],[0,0],form) Stephen> def yzeroaxis(form='k'): v=axis() plot([0,0],v[2:4],form) Stephen> Is this worth adding to the distribution? I doubt it is Stephen> general enough to warrant. Stephen> John: when I do the following: v=arange(5,5) Stephen> plot(v,v**3) xzeroaxis() yzeroaxis() Stephen> the vertical line at x=0 doesn't quite go to top and Stephen> bottom of the plot. This is with 0.62.4. Without testing, my guess is that the autoscale magic is getting in your way. Every plot command calls autoscale, which in the absence of bugs will include the data but may exceed it. Ie, if you plot data with a x range from 0.1 to 9.9, it may set the xlim from 010. Thus, although your idea of using the axis return values to get the min, max is nice, it fails when the autoscale chooses a wider range for nice ticking. The solution I posted a few minutes ago in which the span is plotted in *axes* coordinates rather than data coordinates circumvents this problem. Cheers! JDH 
From: John Hunter <jdhunter@ac...>  20040907 02:47:48

>>>>> "Alan" == Alan G Isaac <aisaac@...> writes: Alan> I'm a newbie to Matplotlib but a longtime gnuplot user. Alan> Using the matlab module, what is the right way to set Alan> xzeroaxis (using gnuplot terminology). Using axis and hline Alan> seems cumbersome, so I assume there is a better way to Alan> implement this common need. Alan> Thank you, Alan Isaac I've not used set xzeroaxis. I googled around a bit and gathered that this draws a horizontal line from xmin to xmax at y=0. There is not equivalent currently in matplotlib so there is no clean and easy way to do this, but Fernando Perez and I talked a bit at scipy about adding some gnuplot compatibility functions and this would fit under that umbrella. I'm interested in getting some feedback about whether folks think this is a good idea. The worry is that we dump too much into the axes to support matlab, IDL and gnuplot users. Here's how you should do this under the current matplotlib. What you want to do is plot a line where the y coord is in data units and equal to zero, and the x coord is in axes units and spans the xrange. The line stretches from left to right regardless of the xlimits. Each axes provides a data transform and an axes transform, so that you can specify lines/text/etc in either coord system; axes coords are 0,0 for lower left and 1,1 for upper right. But what you want to do is mix the data and axes transforms for x and y. The transforms module provides a helper function for this. The following code is freestyle (untested) but should work from matplotlib.transforms import blend_xy_sep_transform ax = gca() trans = blend_xy_sep_transform( ax.transAxes, ax.transData) plot([0,1], [0,0], transform=trans) Try this out and see if it behaves as you like. I can add a methods for this for xzero and yzero if you and others feel this would be useful. Rather than reusing the gnuplot names, it might be better to provide a method that always draws a line from xmin to xmax at a given height regardless of the xlim, and do the same for a vertical line at some x. JDH 
From: Alan G Isaac <aisaac@am...>  20040907 06:46:56

On Mon, 06 Sep 2004, John Hunter apparently wrote: > I've not used set xzeroaxis. I googled around a bit and gathered that > this draws a horizontal line from xmin to xmax at y=0. Right. > Fernando Perez and I talked a bit at scipy about > adding some gnuplot compatibility functions and this would fit under > that umbrella. I'm interested in getting some feedback about whether > folks think this is a good idea. I care about functionality much more than syntax. This is a common need, so it shd be easy to do. > from matplotlib.transforms import blend_xy_sep_transform > ax = gca() > trans = blend_xy_sep_transform( ax.transAxes, ax.transData) > plot([0,1], [0,0], transform=trans) > Try this out and see if it behaves as you like. So far so good. > Rather than reusing the gnuplot names, it might be better to > provide a method that always draws a line from xmin to xmax at a given > height regardless of the xlim, and do the same for a vertical line at > some x. I agree. I actually need the additional functionality. So while we're generalizing let me dream. Focus on the case of vertical lines. The ideal functionality would allow me to use 'vlines' with a special value to indicate ymin and ymax. Ideally this same 'special values' convention would extend to 'fill' (or maybe 'bar'), since I often need event shading. Perhaps the obvious special value is None? fwiw, Alan 
From: John Hunter <jdhunter@ac...>  20040909 15:57:38

From: Alan G Isaac <aisaac@am...>  20040909 16:09:18

On Thu, 09 Sep 2004, John Hunter apparently wrote: > I made a number of simple but useful additions to the matlab interface Very useful!! And very cool as well. Thanks, Alan 
From: Alan G Isaac <aisaac@am...>  20040921 01:50:24

On Thu, 09 Sep 2004, John Hunter apparently wrote: > # set the locations of the xticks > xticks( arange(6) ) > # set the locations and labels of the xticks > xticks( arange(5), ('Tom', 'Dick', 'Harry', 'Sally', 'Sue') ) Just for context, there is much I can do with Matplotlib that I cannot do in gnuplot, and vice versa. Naturally I want the best of both worlds ... In gnuplot, I can set xtics axis to put the tics (both the tics themselves and the accompanying labels) along the zeroaxis (If the zeroaxis is very close to the border, the axis option will move the tic labels to outside the border.) Now that you have given us axhline as a generalization of gnuplot's set xzeroaxis please consider letting xticks take an optional "loc" argument, which could either be "border" or a number to be interpreted as a 'y' value. So, e.g., axhline() xticks(arange(5),loc=0) would draw an xzeroaxis and put the xtics along it. Am I overlooking an obvious way to do this (in the matlab module)? fwiw, Alan 
From: John Hunter <jdhunter@ac...>  20040922 12:34:10

>>>>> "Alan" == Alan G Isaac <aisaac@...> writes: Alan> Now that you have given us axhline as a generalization of Alan> gnuplot's set xzeroaxis please consider letting xticks take Alan> an optional "loc" argument, which could either be "border" Alan> or a number to be interpreted as a 'y' value. Alan> So, e.g., axhline() xticks(arange(5),loc=0) would draw an Alan> xzeroaxis and put the xtics along it. Alan> Am I overlooking an obvious way to do this (in the matlab Alan> module)? Andrew Straw contacted me earlier about a related issue, that is, to be able to offset the x axis line, ticks, and label away from the data region, as in http://dickinson.caltech.edu/research_visualflightcontrol.html. I think this is a generally useful thing. Currently, the axes border is drawn as a rectangle, with a facecolor and the border determined by the rectangle edgecolor. The ticks are then placed on the rectangle border. The proposal is to change this behavior, so that the rectangle border edgecolor becomes the same as the facecolor (ie invisible border). The border is then replaced by four lines, call them bottom, top, left and right. Each of these four lines could be placed independently in axes coords: 0,0,1,1 = left, bottom, right, top. Eg, the bottom line would default to bottom = Line2D([0,1], [0,0], transform=ax.transAxes) ie it the x range would stretch from 01 (leftright) and the y coord would be 0 (bottom) in axes coords. To offset this line below the data range (the white rectangle defined by the axes box) you could, for example, make the ycoord 0.1. To place the x axes in the middle of the axes box, you would make the ycoord 0.5. However, there is a rub. Sometimes you probably want to place the xaxes y location in data units, eg at y=0. Note that this is not the same as y=0 in axes coords, which is always the bottom of the rectangle. This is possible since matplotlib lets you specify the x and y data in different data coordinate systems, eg with http://matplotlib.sourceforge.net/matplotlib.transforms.html#blend_xy_sep_transform, but I think it would take some work to make the interface easy and intuitive. The other trick, from the developer side, is to couple the location of the ticks and tick labels to the y coord of the axes line. Doable, certainly, but would require some redesign because currently they all "know" their location. JDH 
From: Andrew Straw <strawman@as...>  20040924 17:09:51

John Hunter wrote: >>>>>>"Alan" == Alan G Isaac <aisaac@...> writes: >>>>>> >>>>>> > > Alan> Now that you have given us axhline as a generalization of > Alan> gnuplot's set xzeroaxis please consider letting xticks take > Alan> an optional "loc" argument, which could either be "border" > Alan> or a number to be interpreted as a 'y' value. > > Alan> So, e.g., axhline() xticks(arange(5),loc=0) would draw an > Alan> xzeroaxis and put the xtics along it. > > > I tried your suggestion in gnuplot, and I found the results to be ugly  the ticks straddled the axis line, rather than being inside or outside. But I see, in theory, what you mean. >However, there is a rub. Sometimes you probably want to place the >xaxes y location in data units, eg at y=0. Note that this is not the >same as y=0 in axes coords, which is always the bottom of the >rectangle. This is possible since matplotlib lets you specify the x >and y data in different data coordinate systems, eg with >http://matplotlib.sourceforge.net/matplotlib.transforms.html#blend_xy_sep_transform, > > Hmm... that URL is not working for me, but I found what you referenced at http://matplotlib.sourceforge.net/matplotlib.transforms.html >but I think it would take some work to make the interface easy and >intuitive. The other trick, from the developer side, is to couple the >location of the ticks and tick labels to the y coord of the axes line. >Doable, certainly, but would require some redesign because currently >they all "know" their location. > > It seems using scipy's traits object for its ability to set observers on a variable may be useful here. As I said earlier, I may take a stab at this, but I always feel as if I'm "hacking in the dark" when I try and grasp matplotlib's transform and render model... When/if I look at this in greater detail, I'll surely let you know! :) If you're going to a new render model in the future (kiva?), I wonder how useful or longterm would any changes I made now be? Cheers! Andrew 
From: Gary <pajer@in...>  20040907 13:10:57

Stephen Walton wrote: >On Mon, 20040906 at 06:28, Alan G Isaac wrote: > > >>I'm a newbie to Matplotlib but a longtime gnuplot user. >>Using the matlab module, what is the right way to >>set xzeroaxis >> >> > >MATLAB doesn't have anything similar, AFAIK, but the following will >work: > >def xzeroaxis(form='k'): # draw a line at y=0 on the current plot > v=axis() > plot(v[0:2],[0,0],form) > > [...] I've accomplished this feature via: ax = axis() set(gca(). hlines([0.], ax[0], ax[1])[0], linewidth=1) I don't remember why I did it this way instead of just plotting. Maybe I thought is was more clever. Does this method avoid autoscaling? g 
From: John Hunter <jdhunter@ac...>  20040907 14:41:17

>>>>> "Gary" == Gary <pajer@...> writes: Gary> I've accomplished this feature via: ax = axis() set(gca(). Gary> hlines([0.], ax[0], ax[1])[0], linewidth=1) Gary> I don't remember why I did it this way instead of just Gary> plotting. Maybe I thought is was more clever. Does this Gary> method avoid autoscaling? g Yes it does, only because hlines doesn't call autoscale (I just looked it up). This is probably a bug, since I don't see why the plot and hlines method should have different behavior. It looks like an oversight. I think plotting the horizontal extent in axes coords is the proper way to go. JDH 