Dear matplotlib devels,
I wrote a selection widget someone else might find useful. The widget is
based on the slider widget.>
Things I implemented:
* blitting (bar still flashes once when clicked on, sorry about that!)
* Horizontal or vertical direction
* Multiple selection bars on a figure
* interaction between two bars to set a range
I think this is a useful tool, but I would like to see a few
enhancements, some of which you mention below.
Things I struggled with:
* When a bar is dragged towards one of the figure edges too quickly, it gets
stuck in its last recorded position on the graph (that should be the figure
edge).
I think the cause of this is when your mouse leaves the axes, the axes
stops processing events, so it no longer gets updates to move the bar.
I'm not sure what the right solution is though.
* Don't know how to change the mouse pointer when on top of the bar (the <->
pointer for a vertical bar would be nice)
In backend bases there is a cursors enum:::
In [5]: import matplotlib.backend_bases as bb
In [7]: bb.cursors.HAND
Out[7]: 0
In [8]: bb.cursors.MOVE
Out[8]: 3
and you can use the canvas toolbar to change the cursor
In [11]: fig.canvas.toolbar.set_cursor(bb.cursors.MOVE)
* Don't know how to define a range in pixels around the bar (for grabbing),
so used 0.01 of the full range instead
Read the event handling and picking tutorial at
http://matplotlib.sourceforge.net/users/event_handling.html if you
haven't already. I suggest doing the hit testing in figure rather
than data coordinates. So instead of
val = event.xdata
if val < self.val + self.radius ...
do something like the following::
def _update(self, event)
# store the line location in pixel space
self.linex = event.x
def _press(event):
if abs(event.x-self.linex)<=5: # 5 pixels
# hit!
* Haven't implemented dragging when a bar reaches the other bar (set with
set_barmin or set_barmax) but hasn't reached the limit of its range.
How to test:
have mplbar.py and test_bar.py in the same directory, launch test_bar.py
Hope this all makes sense (somehow I doubt it). And like I said, if you guys
like it or want to adapt it further, please do, the code this is based on is
yours after all!
With some additional cleanup along the lines of the above, I would be
happy to accept this. Please document every method (I realize some
exisint code does not meet this standard but we are trying to
improve). Also, please use the rest conventions when documenting new
code; the widgets code has not been ported over but a lot has -- see
http://matplotlib.sourceforge.net/devel/documenting_mpl.html
One feature you may want to consider. I think it would be nice to
have color coded ticks, or possibly a static hspan along the regions
where the bar can slide. Eg, see the following minor modification to
test_bar::
bar1 = mplbar.Bar(ax1,valrange=[10,60],useblit=True, lw=2, color='g')
ax1.axvspan(10, 60, ymin=0, ymax=0.05, facecolor='g', alpha=0.2)
#range 10 to 60, init value set to 60, use blit, blue
bar2 = mplbar.Bar(ax1,valrange=[10,60],valinit=60,useblit=True,
lw=2, color='b')
ax1.axvspan(10, 60, ymin=0.95, ymax=1.0, facecolor='blue', alpha=0.2)
#range 30 to +inf (None = no bound), default set to 30, use blit,
horizontal line, red
bar3 = mplbar.Bar(ax1,valrange=[30,None],useblit=True,
direction='horizontal', lw=2, color='r')
ax1.axhspan(30, 2*npts, xmin=0.95, xmax=1.0, facecolor='red', alpha=0.2)
Of course the use can always add this, so I am not sure if it is worth
building in... but support for something like this via a kwar might be
nice, eg
Bar(blah, ..., showrange=True, rangespan=[0.95, 1.0])
JDH
···
On Wed, Nov 26, 2008 at 5:34 AM, Egor Zindy <ezindy@...149...> wrote: