On Wed, Sep 26, 2012 at 3:14 PM, Michael Droettboom <mdroe@...> wrote:
> On 09/26/2012 04:35 AM, Todd wrote:
> On Mon, Sep 24, 2012 at 3:33 PM, Todd <toddrjen@...> wrote:
>> I would like to add a new plot type to matplotlib. Of course I am willing
>> to implement it myself, but I want to confirm that it is acceptable and iron
>> out the implementation details and API first so there are no major surprises
>> when I submit it.
>> I tentatively am calling the plot type an "EventRaster" plot (name
>> suggestions, along with any other suggestions, are welcome). The plot is
>> made up if horizontal rows of identical vertical lines and/or markers. Each
>> line or marker represents a discrete event, and each row represents a single
>> sequence of events (such as a trial). The x-axis position of the line or
>> marker identifies the location of the event by some measure. An example of
>> what such a plot often looks like is below.
>> This sort of plot is used ubiquitously in neuroscience. It is used to
>> show the time of discrete neural (brain cell) events (called "spikes") over
>> time in repeated trials, and is generally called a spike raster, raster
>> plot, or raster graph. However, it can be used in any situation where you
>> are only concerned with the position of events but not their amplitude,
>> especially if you want to look for patterns in those events or look for
>> differences between multiple sequences of events.
>> Plotting the timing of events is an obvious use case, such as photons
>> hitting photodetectors, radioactive decay events, arrival of patients to
>> hospitals, calls to hotlines, or car accidents in cities. However, the
>> events do not have to be relative to time. It could be position, for
>> example, such as tree rings along bore holes, road crossings along railroad
>> tracks, layers in sediment cores, or particular sequences along a DNA
>> I'll cover possible implementation details in the next email if everyone
>> thinks this is a good idea.
> So does anyone think this would be a useful plot type? If so I can explain
> how I plan to implement it and we can discuss changes or improvements to
> Sorry to not get back to you sooner -- a number of us are busy here getting
> the 1.2.0 release ready at the moment. I think this is definitely a
> worthwhile plot type to add. Similar plots are used in Computer Science,
> for example, to visualize the execution of multi-threaded applications, or
> other scheduling problems. I'd personally use it for that.
> So, yes, let's start talking implementation. Or, if easier, you could just
> submit a pull request and we can go from there. Whatever method seems most
> appropriate to you.
I would prefer to get the details worked out before I start coding
since there are a few different approaches. First thing is to figure
out a good name, I am not sure this is the best name for it.
Assuming we go with the name, here is my proposed call signature:
EventRaster(x, offset=0, height=1, **kargs)
x is a 1D or 2D array. If a 1D array, it create a single row of
lines. If it is a 2D array, it creates one row of lines for each row
in the array.
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.
height determines the length of the lines. By default the line
stretches from offset-.5 to offset+.5. If height is defined the line
stretches from offset-.5*height to offset+.5*height.
**kargs are the same as those of plot().
An important thing to note is that the marker will only appear the
center point of each line, not at the ends.
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)
In this case y behaves the same as x, except it creates columns of
lines instead of rows. If y is specified x cannot be specified, and
vice versus. If keyword arguments are not used, it assumes x is what
I don't know which approach is better.
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.
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.
Internally, the lines will be length 3 Line2D objects, with the 3
points being offset-.5*height, offset, and offset+.5*height.
So what does everyone think of this approach? Does anyone have any
comments, suggestions, or just think the approach is nonsense? It
would certainly be possible to implement this based more on existing
classes, but I don't think the implementation would be as clean, as
maintainable, or as extensible as this implementation.