<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Thanks Antony, <div class=""><br class=""></div><div class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Feb 8, 2018, at  8:09 AM, Antony Lee <<a href="mailto:antony.lee@berkeley.edu" class="">antony.lee@berkeley.edu</a>> wrote:</div></blockquote><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">From the email of Ted it appears that these are not sufficient to represent all kinds of relevant units.  In particular, I was at some point hoping to completely work in deunitized data internally, *including the plotting*, and rely on the fact that if the deunitized and the unitized data are usually linked by an affine transform, so the plotting part doesn't need to convert back to unitized data and we only need to place and label the ticks accordingly; however Ted mentioned relativistic units, which imply the use of a non-affine transform.  So I think it would also be really helpful if JPL could release some reasonably documented unit library with their actual use cases (and how it differs from pint & astropy.units), so that we know better what is actually needed (I believe carrying the JPL unit code in our own code base is a mistake).</div></div></div></blockquote><div><br class=""></div><div>… or an indication that the astropy (for instance) use-case is good enough to base an API around.  </div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">As for the public vs private, or rather unitized vs deunitized API discussion, I believe a relatively simple and consistent line would be to make Axes methods unitized and everything else deunitized (but with clear ways to convert to and from unitized data when not using Axes methods).</div></div></div></blockquote><div><br class=""></div><div>I was going to suggest that distinction as well.  Anything that requires `axes.add_artist` is deunitized since we use those artists all over the place internally and keeping track of whether we have units or not would be really hard.  </div><div><br class=""></div><div>Cheers,   Jody</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">Antony</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">2018-02-07 16:33 GMT+01:00 Drain, Theodore R (392P) <span dir="ltr" class=""><<a href="mailto:theodore.r.drain@jpl.nasa.gov" target="_blank" class="">theodore.r.drain@jpl.nasa.gov</a>></span>:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">That sounds fine to me.  Our original unit prototype API actually had conversions for both directions but I think the float->unit version was removed (or really moved) when the ticker/formatter portion of the unit API was settled on.<br class="">
<br class="">
Using floats/numpy arrays internally is going to easier and faster so I think that's a plus.  The biggest issue we're going to run in to is what's defined as "internal" vs part of the unit API.  Some things are easy like the Axes/Axis API.  But we also use low level API's like the patches.  Are those unitized?  This is the pro and con of using something like Python where basically everything is public.  It makes it possible to do lots of things, but it's much harder to define a clear library with a specific public API.<br class="">
<br class="">
Somewhere in the process we should write a proposal that outlines which classes/methods are part of the unit api and which are going to be considered internal.  I'm sure we can help with that effort.<br class="">
<br class="">
That also might help clarify/influence code structure - if internal implementation classes are placed in a sub-package inside MPL 3.0, it becomes clearer to people later on what the "official' public API vs what can be optimized to just use floats.  Obviously the dev's would need to decide if that kind of restructuring is worth it or not.<br class="">
<br class="">
Ted<br class="">
<br class="">
______________________________<wbr class="">__________<br class="">
From: David Stansby <<a href="mailto:dstansby@gmail.com" class="">dstansby@gmail.com</a>><br class="">
Sent: Wednesday, February 7, 2018 3:42 AM<br class="">
To: Jody Klymak<br class="">
Cc: Drain, Theodore R (392P); matplotlib development list<br class="">
Subject: Re: [Matplotlib-devel] Units discussion...<br class="">
<span class=""><br class="">
Practically, I think what we are proposing is that for unit support the user must supply two functions for each axis:<br class="">
<br class="">
</span>  *   A mapping from your unit objects to floating point numbers<br class="">
  *   A mapping from those floats back to your unit objects<br class="">
<span class=""><br class="">
As far as I know function 2 is new, and doesn't need to be supplied at the moment. Doing this would mean we can convert units as soon as they enter Matplotlib, only ever have to deal with floating point numbers internally, and then use the second function as late as possible when the user requests stuff like e.g. the axis limits.<br class="">
<br class="">
Also worth noting that any major change like this will go in to Matplotlib 3.0 at the earliest, so will be python 3 only.<br class="">
<br class="">
David<br class="">
<br class="">
</span><span class="">On 7 February 2018 at 06:06, Jody Klymak <<a href="mailto:jklymak@uvic.ca" class="">jklymak@uvic.ca</a><mailto:<a href="mailto:jklymak@uvic.ca" class="">jklyma<wbr class="">k@uvic.ca</a>>> wrote:<br class="">
Dear Ted,<br class="">
<br class="">
Thanks so much for engaging on this.<br class="">
<br class="">
Don’t worry, nothing at all is changing w/o substantial back and forth, and OK from downstream users.   I actually don’t think it’ll be a huge change, probably just some clean up and better documentation.<br class="">
<br class="">
FWIW, I’ve not personally done much programming w/ units, just been a bit perplexed by their inconsistent and (to my simple mind) convoluted application in the codebase.  Having experience from people who try to use them everyday will be absolutely key.<br class="">
<br class="">
Cheers,   Jody<br class="">
<br class="">
</span><span class="">> On Feb 6, 2018, at  14:17 PM, Drain, Theodore R (392P) <<a href="mailto:theodore.r.drain@jpl.nasa.gov" class="">theodore.r.drain@jpl.nasa.gov</a><wbr class=""><mailto:<a href="mailto:theodore.r.drain@jpl.nasa.gov" class="">theodore.r.drain@jpl.<wbr class="">nasa.gov</a>>> wrote:<br class="">
><br class="">
> We use units for everything in our system (in fact, we funded John Hunter originally to add in a unit system so we could use MPL) so it's a crucial system for us.  In our system, we have our own time classes (which handle relativistic time frames as well as much higher precision representations) and a custom unit system for floating point values.<br class="">
><br class="">
> I think it's important to talk about these changes in concrete terms.  I understand the words you're using,  but I'm not really clear on what the real proposed changes are.  For example, the current unit API returns a units.AxisInfo object so the converter can set the formatter and locators to use.  Is that what you mean in the 2nd paragraph about ticks and labels?  Or is that changing?<br class="">
><br class="">
> The current unit api is pretty simple and in units.ConversionInterface.  Are any of these changes going to change the conversion API?  (note - I'm not against changing it - I'm just not sure if there are any changes or not).<br class="">
><br class="">
> Another thing to consider:  many of the examples people use are scripts which make a plot and stop.  But there are other use cases which are more complicated and stress the system in different ways.  We write several GUI applications (in PyQt) that use MPL for plotting.  In these cases, the user is interacting with the plot to add and remove artists, change styles, modify data, etc etc.  So having a good object oriented API for modifying things after construction is important for this to work.  So when units are involved, it can't be a "convert once at construction" and never touch units again.   We are constantly adjusting limits, moving artists, etc in unitized space after the plot is created.<br class="">
><br class="">
> So in addition to the ConversionInterface API, I think there are other items that would be useful to explicitly spelled out.  Things like which API's in MPL should accept units and which won't and which methods return unitized data and which don't.   It would be nice if there was a clear policy on this.  Maybe one exists and I'm not aware of it - it would be helpful to repeat it in a discussion on changing the unit system.  Obviously I would love to have every method accept and return unitized data :-).<br class="">
><br class="">
> I bring this up because I was just working on a hover/annotation class that needed to move a single annotation artist with the mouse.  To move the annotation box the way I needed to, I had to set to one private member variable, call two set methods, use attribute assignment for one value, and set one semi-public member variable - some of which work with units and some of which didn't.  I think having a clear "this kind of method accepts/returns units" policy would help when people are adding new accessors/methods/variables to make it more clear what kind of data is acceptable in each.<br class="">
><br class="">
> Ted<br class="">
> ps: I may be able to help with some resources to work on any unit upgrades, but to make that happen I need to get a clear statement of what problem is being solved and the scope of the work so I can explain to our management why it's important.<br class="">
><br class="">
> ______________________________<wbr class="">__________<br class="">
</span>> From: Matplotlib-devel <matplotlib-devel-bounces+ted.<wbr class="">drain=<a href="mailto:jpl.nasa.gov@python.org" class="">jpl.nasa.gov@python.org</a><<wbr class="">mailto:<a href="mailto:jpl.nasa.gov@python.org" class="">jpl.nasa.gov@python.org</a><wbr class="">>> on behalf of Jody Klymak <<a href="mailto:jklymak@uvic.ca" class="">jklymak@uvic.ca</a><mailto:<a href="mailto:jklymak@uvic.ca" class="">jklyma<wbr class="">k@uvic.ca</a>>><br class="">
<span class="">> Sent: Saturday, February 3, 2018 9:25 PM<br class="">
> To: matplotlib development list<br class="">
> Subject: [Matplotlib-devel] Units discussion...<br class="">
><br class="">
> Hi all,<br class="">
><br class="">
> To carry on the gitter discussion about unit handling, hopefully to lead to a more stringent documentation and implimentation….<br class="">
><br class="">
> In response to @anntzer I thought about the units support a bit - it seems that rather than a transform, a more straightforward approach is to have the converter map to float arrays in a unique way.  This float mapping would be completely analogous to `date2num` in `dates`, in that it doesn’t change and is perfectly invertible without matplotlib ever knowing about the unit information, though the axis could store it for the the tick locators and formatters.  It would also have an inverse that would supply data back to the user in unit-aware data (though not necessarily in the unit that the user supplied.  e.g. if they supply 8*in, the and the converter converts everything to meter floats, then the returned unitized inverse would be 0.203*m, or whatever convention the converter wants to supply.).<br class="">
><br class="">
> User “unit” control, i.e. making the plot in inches instead of m, would be accomplished with ticks locators and formatters.  Matplotlib would never directly convert between cm and inches (any more than it converts from days to hours for dates), the downstream-supplied tick formatter and labeller would do it.<br class="">
><br class="">
> Each axis would only get one converter, set by the first call to the axis. Subsequent calls to the axis would pass all data (including bare floats) to the converter.  If the converter wants to pass bare floats then it can do so.  If it wants to accept other data types then it can do so.  It should be possible for the user to clear or set the converter, but then they should know what they are doing and why.<br class="">
><br class="">
> Whats missing?  I don’t think this is wildly different than what we have, but maybe a bit more clear.<br class="">
><br class="">
> Cheers,   Jody<br class="">
><br class="">
><br class="">
><br class="">
><br class="">
> ______________________________<wbr class="">_________________<br class="">
> Matplotlib-devel mailing list<br class="">
</span>> <a href="mailto:Matplotlib-devel@python.org" class="">Matplotlib-devel@python.org</a><<wbr class="">mailto:<a href="mailto:Matplotlib-devel@python.org" class="">Matplotlib-devel@<wbr class="">python.org</a>><br class="">
<span class="">> <a href="https://mail.python.org/mailman/listinfo/matplotlib-devel" rel="noreferrer" target="_blank" class="">https://mail.python.org/<wbr class="">mailman/listinfo/matplotlib-<wbr class="">devel</a><br class="">
> ______________________________<wbr class="">_________________<br class="">
> Matplotlib-devel mailing list<br class="">
</span>> <a href="mailto:Matplotlib-devel@python.org" class="">Matplotlib-devel@python.org</a><<wbr class="">mailto:<a href="mailto:Matplotlib-devel@python.org" class="">Matplotlib-devel@<wbr class="">python.org</a>><br class="">
<span class="">> <a href="https://mail.python.org/mailman/listinfo/matplotlib-devel" rel="noreferrer" target="_blank" class="">https://mail.python.org/<wbr class="">mailman/listinfo/matplotlib-<wbr class="">devel</a><br class="">
<br class="">
______________________________<wbr class="">_________________<br class="">
Matplotlib-devel mailing list<br class="">
</span><a href="mailto:Matplotlib-devel@python.org" class="">Matplotlib-devel@python.org</a><<wbr class="">mailto:<a href="mailto:Matplotlib-devel@python.org" class="">Matplotlib-devel@<wbr class="">python.org</a>><br class="">
<div class="HOEnZb"><div class="h5"><a href="https://mail.python.org/mailman/listinfo/matplotlib-devel" rel="noreferrer" target="_blank" class="">https://mail.python.org/<wbr class="">mailman/listinfo/matplotlib-<wbr class="">devel</a><br class="">
<br class="">
______________________________<wbr class="">_________________<br class="">
Matplotlib-devel mailing list<br class="">
<a href="mailto:Matplotlib-devel@python.org" class="">Matplotlib-devel@python.org</a><br class="">
<a href="https://mail.python.org/mailman/listinfo/matplotlib-devel" rel="noreferrer" target="_blank" class="">https://mail.python.org/<wbr class="">mailman/listinfo/matplotlib-<wbr class="">devel</a><br class="">
</div></div></blockquote></div><br class=""></div>
_______________________________________________<br class="">Matplotlib-devel mailing list<br class=""><a href="mailto:Matplotlib-devel@python.org" class="">Matplotlib-devel@python.org</a><br class="">https://mail.python.org/mailman/listinfo/matplotlib-devel<br class=""></div></blockquote></div><br class=""></div></body></html>