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

Reply via email to