On 11/11/2012 11:51 PM, Todd wrote:
> On Thu, Sep 27, 2012 at 8:18 PM, Todd <toddr...@gmail.com> wrote:
>> On Thu, Sep 27, 2012 at 1:44 PM, Todd <toddr...@gmail.com> wrote:
>>> On Thu, Sep 27, 2012 at 1:12 PM, Damon McDougall
>>> <damon.mcdoug...@gmail.com> wrote:
>>>> Hi Todd,
>>>>
>>>> Firstly, thanks for taking the time to crystallise your thoughts in
>>>> words first. This is one of my bad habits; I tend to rush into things.
>>>>
>>>> I have some feedback for you, hopefully we can all work together to
>>>> get this right. It's difficult when something new gets implemented and
>>>> someone expects it to do something and the only way to resolve it is
>>>> to break the calling API.
>>> Where is API broken?
>>>
>>>> Anyway, I hope you'll find my comments
>>>> helpful at the least. I also encourage others to weigh in with
>>>> opinions and ideas.
>>> Okay, I will discuss the rationale.  I will snip out anything you
>>> agree on for brevity.
>>>
>>>>> Assuming we go with the name, here is my proposed call signature:
>>>>>
>>>>> EventRaster(x, offset=0, height=1, **kargs)
>>>> CamelCase is discouraged for method names. Perhaps 'eventraster'?
>>> Fair enough.
>>>
>>>> Also, we could also let **kwargs swallow the 'offset' and 'height'
>>>> keyword arguments. Then the user isn't constrained by which order to
>>>> put them in. The downside of this approach is that introspection is
>>>> more difficult.
>>> I don't understand the advantage of this approach.  If you use keyword
>>> arguments, then the order doesn't matter.  So with the approach above
>>> you can use keyword arguments, in which case you can use whatever
>>> order they want, or you can use positional arguments.  On the other
>>> hand putting it in **kwargs, we lose the ability to use positional
>>> arguments.  So we lose nothing by allowing both positional and keyword
>>> arguments.  It is also easier to implement.
>>>
>>>>> offset determines the positions of the rows.  By default, the first
>>>>> row is placed with the line center y=0, and subsequent rows are placed
>>>>> with the line centers at increasing 1-unit increments.  If offset is
>>>>> defined and is a scalar, the first row is placed at the offset, and
>>>>> subsequent rows are placed at increasing 1-unit increments.  If offset
>>>>> is an array, it must be a 1D array of the same length as the second
>>>>> dimension of x.  In this case each element in offset determines the
>>>>> center of the corresponding row in the plot.
>>>> How about letting offset be either: a) a scalar, determining the
>>>> offset of all rows equally; or b) an array, determining the offset of
>>>> each row individually.
>>> Because people are almost never going to want to have all the lines
>>> stacked right on top of each other.  The plot would be indecipherable
>>> that way.  The defaults are chosen to handle the most common use-cases
>>> most easily.
>>>
>>>> In fact, why plot each row at integer y
>>>> coordinates? Could we allow for an optional y-coordinate array, each
>>>> element of which would be the y-coordinate at which to plot a row of
>>>> lines. Then you wouldn't need offset.
>>> That is exactly what offset does if you pass an array.
>>>
>>>>> If this is going to be used to implement rug plots, it would need some
>>>>> way to handle columns of horizontal lines in addition to rows of
>>>>> vertical lines.  I see two ways to implement this.  First is to have
>>>>> to plot types, perhaps HEventRaster and VEventRaster.  The first would
>>>>> be as described above, while the second would be similar but
>>>>> everything rotated 90 degrees.  Another possibility is to change the
>>>>> call signature to this:
>>>>>
>>>>> EventRaster(x, y=None, offset=0, height=1, **kargs)
>>>> I think accepting an 'orientation' kwarg, which can take either
>>>> 'horizontal' or 'vertical', determining the orientation of the lines
>>>> and reversing the roles of the x and y arrays.
>>> That would work as well.  Probably cleaner that way
>>>
>>>>> The function will return a list of a new collection type I am
>>>>> tentatively calling EventCollection.  My thinking would be this would
>>>>> be a subclass of a new collection type called GenericLineCollection,
>>>>> which the current LineCollection would also subclass.  They would
>>>>> share things like the color handling and segment handling, however the
>>>>> segment handling will be a "private" method that LineCollection will
>>>>> have a public wrapper for.  On the other hand methods to set or add
>>>>> segments will remain private in EventCollection, although there will
>>>>> be a method to return the segments if an artist really wants to
>>>>> manipulate individual segments.
>>>> Why can't we just use LineCollection? I don't see a good reason to
>>>> create a new collection class here; the plot is simple.
>>> Explained below.
>>>
>>>>> The reason for doing it this way is that manipulating individual rows
>>>>> of events should be very common, such as changing their position,
>>>>> color, marker, width, and so on.  On the other hand manipulating lines
>>>>> individually should not be as common, although still supported.
>>>> Fair enough, then maybe a better idea is to create your own
>>>> EventRaster class (note camel case) to hold all the relevant data in
>>>> arrays. Then make a 'construct_raster' method could return a
>>>> LineCollection. Then again, weren't you passing extra kwargs to
>>>> 'plot'? This approach would surely use ax.add_lines or
>>>> ax.add_linecollection something (I can't remember what it's called).
>>> The whole point of creating a new collection type is that artists will
>>> be able to manipulate individual sets of events.
>>>
>>> For example, with an ordinary LineCollection it will be extremely
>>> difficult to change the marker type, since doing so will change the
>>> marker for all 3 points on each segment rather than just the middle
>>> point.  So if someone makes the plot, than wants to set rows to have
>>> different marker types instead of being lines, they can do that if we
>>> use a new collection class.  But if we use LineCollection this becomes
>>> much more difficult.
>>>
>>> Similarly, with a LineCollection the lines lose their status as
>>> objects with a single distinct position.  They become objects with 3
>>> 2D coordinates.  So if someone wants to add more events to the end,
>>> they need to take care of handling the x and y coordinates, making
>>> sure the x coordinates are the same and taking the y coordinates from
>>> one of the existing lines. Similarly changing the height or vertical
>>> position of all the objects is complicated, having to manually
>>> calculate and modify the y coordinates of each point in each segment.
>>>
>>> Again, the idea here is to make the most common use-cases as easy as
>>> possible.  LineCollection objects aren't really suited to the sort of
>>> artistic changes that are typical with this sort of plot.
>>>
>>> In fact I would say that having a separate collection class is central
>>> to this idea.  If users aren't able to manipulate the set of events as
>>> such after they create the plot, then there really isn't any advantage
>>> over just using a vlines plot. Calculating the ymin and ymax is one
>>> line of code each, it is the artistic changes that save many lines of
>>> code and a lot of complexity.
>> I would also like to add that the new collection object would be
>> useful outside of this plot type.
>>
>> For example if someone wanted to create a rug plot as Nathaniel
>> described, and they want those along the same axes as the main plot,
>> then they would most likely not be be using the plot function, but
>> rather creating two individual collection objects in an existing
>> figure.
>>
>> I can imagine other cases besides a strict rug plot where adding such
>> a collection object could be useful.
> Now that 1.2 is out, can we revisit this?  I would like to get it
> implemented for the next feature release.
>

Absolutely.  I think the next step, once you have an implementation, 
would be to submit a pull request and we can all help with a review.

(BTW -- feel free to submit pull requests at any point in a release 
cycle -- we have both a master and a maintenance branch, so we can work 
on new stuff and stable stuff at the same time).

Mike


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_nov
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to