John, Thank you for your thorough and thoughtful reply. OK, I am convinced. I had not realized that the present line-drawing code actually is omitting nonpositive points, but now I see the Line.get_plottable() method.
I have committed changes to svn that I think will be helpful--maybe good enough for now. From the CHANGELOG: 2006-12-28 Improved error message for nonpositive input to log transform; added log kwarg to bar, barh, and hist, and modified bar method to behave sensibly by default when the ordinate has a log scale. (This only works if the log scale is set before or by the call to bar, hence the utility of the log kwarg.) - EF Examples: This makes a sensible plot that behaves well under zooming and panning: hist(randn(1000), log=True) show() The following still generates an exception: hist(randn(1000)) gca().set_yscale('log') show() but the traceback is more informative and ends with: /usr/local/lib/python2.4/site-packages/matplotlib/patches.py in draw(self, renderer) 183 184 verts = self.get_verts() --> 185 tverts = self.get_transform().seq_xy_tups(verts) 186 187 renderer.draw_polygon(gc, rgbFace, tverts) ValueError: Cannot take log of nonpositive value I have not put in any form of your suggested addition to set_yscale and set_xscale. Maybe I should, but I am hoping that the changes above are sufficient. Eric John Hunter wrote: >>>>>> "Eric" == Eric Firing <[EMAIL PROTECTED]> writes: > > Eric> Adjusting zero and negative values (or maybe just zero) > Eric> would be unacceptable in a numerics library, but in the > Eric> context of our graphical transforms it is analogous to > Eric> clipping, and this we do all the time--we don't raise an > Eric> exception if someone tries to plot outside the box. (This > Eric> clipping strategy to handle nonpositive values is present > Eric> already in the LogLocator.) > > I'm more comfortable dropping points than I am altering the data. > Consider some use case like > > ax.hist(...) > rect = Rectangle(...) > ax.add_patch(rect) > ax.set_xscale('log') > > In set_xscale we only see a bunch of rectangles. User defined > rectangles may be used to store data (eg the JPL uses custom bars with > xlimits that are the start and stop times when orbiting spacecraft are > within view of a ground station). Some of these users will also want > to "pick" the rectangle and inspect the data values. If we are > altering them, they have no guarantee that what they put in is what > they get out. Now we might argue that they get what they deserve if > they are using invalid data for a log scale, but one good solution in > my view is to fail noisily with helpful messages, and provide an easy > interface to do it right. > > But if I am missing your point or you have an implementation that will > address these concerns, I'm certainly open to them. One possibility > is to flag artists that we create internally (eg hist) and take more > liberty with these, or have some flag like the Artist "clip_on" > property which allows the user to control whether their data is > mutable to support "helpful" alterations for log or other > transformations. > > Eric> We can use such a small adjustment value that a problem such > Eric> as you mention above is highly unlikely--and note that > Eric> floating point itself has limitations, and does not permit > Eric> arbitrarily small or large numbers. Furthermore, note that > > Eric> the user can always take advantage of the bottom kwarg. And > Eric> if in some extreme case the user has not used the bottom > Eric> kwarg and the bars really are shorter than the adjustment > Eric> value, it will probably be quite obvious. > > The other thing to think about is choosing a bottom so that the > natural range of the tops is revealed. Eg if the bottom is 1e-200, > all the bars will appear the same height in many cases. > > Eric> It is in ordinary line plotting that adjusting the value > Eric> could be misleading--it plots an extremely small number (if > Eric> the data limits are set to include it) instead of zero. > Eric> Maybe this is enough of a drawback to nix the whole idea. > > I am happy with the current behavior of culling the non-positive > points. matlab does it and noone has complained here. There is a > difference in lines created with "plot" and bars created with hist: in > the former case the users explicitly picked the x,y points. In the > latter they implicitly do so with a default bottom kwarg that they may > have overlooked. This suggests to me that we need not treat the two > cases the same. > > Eric> Every alternative that you propose is more complicated and > Eric> less comprehensive than the low-level adjustment, however, > Eric> and I see little if any real advantage to the alternatives. > > If you would like to take a stab at an implementation I am happy to be > persuaded (with caveats below). In the simple case of > > ax.hist() > ax.set_xscale('log') > > this would indeed be fairly easy because you know how the data were > created. In the general case where the user has added lots-o-patches > to the axes, it may not be easy to do well. I'm still inclined to the > "explicit is better than implicit" and either require them to do one of > > 1) use the bottom kwarg > > 2) set log scaling before calling hist -- we can make the default > bottom=None and do different things for linear and log scaling > > 3) use a loghist function > > Eric> If you still don't want the adjustment, then the easiest way > Eric> to improve the error message would be to raise a Python > Eric> exception instead of a c++ error in places like > > Eric> for(int i=0; i < length; i++) { if (x<=0) { throw > Eric> std::domain_error("Cannot take log of nonpositive value"); } > Eric> else newx[i] = log10(x[i]); > Eric> } > > Eric> The domain error message above is informative, but it never > Eric> makes it out to the user. > > I really don't feel too strongly about this -- my gut reaction is that > a helpful message and an easy way to fix it is enough and it won't get > us into a possible quagmire of trying to be too smart. Personally, I > don't like it when computers try to be too helpful (think MS windows > and clippy); I like it when they do what I tell them to do. With the > snippet I posted previously we can easily warn them before doing the > transformation and with bottom=None we can handle the case when the > log scale is set before the call to hist. That in conjunction with > some additional docstrings in hist should work reasonably well. > > That said, if you want to try something more ambitious I won't get in > your way. I recommend at a minimum that you have some artist flag > that governs whether mpl can make helpful data alterations (just as we > do with clip) so the power user can turn it off. > > JDH ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ Matplotlib-users mailing list Matplotlib-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-users