Re: [Matplotlib-users] pick markers only but not the connecting line

2014-06-07 Thread Eric Firing
On 2014/06/07, 5:03 PM, C M wrote:
>
>
>
> On Sat, Jun 7, 2014 at 10:18 PM, Eric Firing  > wrote:
>
> On 2014/06/07, 4:12 PM, C M wrote:
>  > I had been using a custom function (written originally by
> Jae-Joon and
>  > modified a little by me...quite a long time back now) that was
> working
>  > to allow point picking of markers, but *not* the line connecting
> them.
>  > However, I've now discovered with the help of this list that the
>  > function I am using has the disadvantage that if there are more
> than 100
>  > data points, I can't get the correct index for the picked marker
> (turned
>  > out not to be a mpl bug:
>  > https://github.com/matplotlib/matplotlib/issues/3124).
>  >
>  > So I can just use the default pick event, but then the user can pick
>  > anywhere on the connecting line, which is meaningless in this
> use--so I
>  > don't want them to be able to pick on the connecting line.
>
> Why not just execute plot twice, once with the markers, with picking
> activated, and a second time with the line, with picking inactive (the
> default).
>
> Eric
>
>
> That is so simple, and I hadn't thought of it at all.  Thank you!  My
> only concerns would be for slowness of plotting if there are a lot of
> points and just code simplicity, and so if there could be some other way
> with a custom function for the picker that would do this, I would
> probably prefer that. But maybe neither of these are particularly
> important concerns.

I think you will find plotting two lines instead of one is not at all 
prohibitive with respect to speed; especially when you are zooming, so 
that the number of points being plotted is not so large.

As for simplicity, two calls to a standard function with almost the same 
arguments beats an arcane special-purpose function!

If you want to make your own picker, though, it looks like you could use 
a slight modification of Line2D.contains(); it would be just a matter of 
copying it and replacing this section

 # Check for collision
 if self._linestyle in ['None', None]:
 # If no line, return the nearby point(s)
 d = (xt - mouseevent.x) ** 2 + (yt - mouseevent.y) ** 2
 ind, = np.nonzero(np.less_equal(d, pixels ** 2))
 else:
 # If line, return the nearby segment(s)
 ind = segment_hits(mouseevent.x, mouseevent.y, xt, yt, 
pixels)


with the code in the first option--that is, without checking the 
_linestyle.  You would also need to remove the first two lines after the 
docstring.

Eric

>
> Che
>
>
>
>
>
> --
> Learn Graph Databases - Download FREE O'Reilly Book
> "Graph Databases" is the definitive new guide to graph databases and their
> applications. Written by three acclaimed leaders in the field,
> this first edition is now available. Download your free book today!
> http://p.sf.net/sfu/NeoTech
>
>
>
> ___
> Matplotlib-users mailing list
> Matplotlib-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>


--
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their 
applications. Written by three acclaimed leaders in the field, 
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech
___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Re: [Matplotlib-users] pick markers only but not the connecting line

2014-06-07 Thread C M
On Sat, Jun 7, 2014 at 10:18 PM, Eric Firing  wrote:

> On 2014/06/07, 4:12 PM, C M wrote:
> > I had been using a custom function (written originally by Jae-Joon and
> > modified a little by me...quite a long time back now) that was working
> > to allow point picking of markers, but *not* the line connecting them.
> > However, I've now discovered with the help of this list that the
> > function I am using has the disadvantage that if there are more than 100
> > data points, I can't get the correct index for the picked marker (turned
> > out not to be a mpl bug:
> > https://github.com/matplotlib/matplotlib/issues/3124).
> >
> > So I can just use the default pick event, but then the user can pick
> > anywhere on the connecting line, which is meaningless in this use--so I
> > don't want them to be able to pick on the connecting line.
>
> Why not just execute plot twice, once with the markers, with picking
> activated, and a second time with the line, with picking inactive (the
> default).
>
> Eric
>

That is so simple, and I hadn't thought of it at all.  Thank you!  My only
concerns would be for slowness of plotting if there are a lot of points and
just code simplicity, and so if there could be some other way with a custom
function for the picker that would do this, I would probably prefer that.
But maybe neither of these are particularly important concerns.

Che
--
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their 
applications. Written by three acclaimed leaders in the field, 
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Re: [Matplotlib-users] pick markers only but not the connecting line

2014-06-07 Thread Eric Firing
On 2014/06/07, 4:12 PM, C M wrote:
> I had been using a custom function (written originally by Jae-Joon and
> modified a little by me...quite a long time back now) that was working
> to allow point picking of markers, but *not* the line connecting them.
> However, I've now discovered with the help of this list that the
> function I am using has the disadvantage that if there are more than 100
> data points, I can't get the correct index for the picked marker (turned
> out not to be a mpl bug:
> https://github.com/matplotlib/matplotlib/issues/3124).
>
> So I can just use the default pick event, but then the user can pick
> anywhere on the connecting line, which is meaningless in this use--so I
> don't want them to be able to pick on the connecting line.

Why not just execute plot twice, once with the markers, with picking 
activated, and a second time with the line, with picking inactive (the 
default).

Eric

>
> My goal is to have a custom function that will serve *both* purposes:
> allow picking the markers only, not the line, of a set of data of any
> length while returning the correct index of that marker/data point.  But
> the code in the custom function is mostly above my head, was written for
> mpl 0.99 or so, and I don't know how to modify it to get both purposes
> achieved.
>
> I attach the current sample again, with the problematic custom picker
> function, "contains_points()".  Thanks for any suggestions or help.
>
> Che
>
>
>
> --
> Learn Graph Databases - Download FREE O'Reilly Book
> "Graph Databases" is the definitive new guide to graph databases and their
> applications. Written by three acclaimed leaders in the field,
> this first edition is now available. Download your free book today!
> http://p.sf.net/sfu/NeoTech
>
>
>
> ___
> Matplotlib-users mailing list
> Matplotlib-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>


--
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their 
applications. Written by three acclaimed leaders in the field, 
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech
___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


[Matplotlib-users] pick markers only but not the connecting line

2014-06-07 Thread C M
I had been using a custom function (written originally by Jae-Joon and
modified a little by me...quite a long time back now) that was working to
allow point picking of markers, but *not* the line connecting them.
However, I've now discovered with the help of this list that the function I
am using has the disadvantage that if there are more than 100 data points,
I can't get the correct index for the picked marker (turned out not to be a
mpl bug:  https://github.com/matplotlib/matplotlib/issues/3124).

So I can just use the default pick event, but then the user can pick
anywhere on the connecting line, which is meaningless in this use--so I
don't want them to be able to pick on the connecting line.

My goal is to have a custom function that will serve *both* purposes:
allow picking the markers only, not the line, of a set of data of any
length while returning the correct index of that marker/data point.  But
the code in the custom function is mostly above my head, was written for
mpl 0.99 or so, and I don't know how to modify it to get both purposes
achieved.

I attach the current sample again, with the problematic custom picker
function, "contains_points()".  Thanks for any suggestions or help.

Che

import matplotlib.pyplot as plt
import numpy as np

def contains_points(line, mouseevent):

line.pickradius = 5
# Make sure we have data to plot
if line._invalidy or line._invalidx:
line.recache()
if len(line._xy)==0: return False,{}
# Convert points to pixels
if line._transformed_path is None:
   line._transform_path()
path, affine = line._transformed_path.get_transformed_points_and_affine()
path = affine.transform_path(path)
xy = path.vertices
xt = xy[:, 0]
yt = xy[:, 1]

pixels = line.figure.dpi/72. * line.pickradius
d = (xt-mouseevent.x)**2 + (yt-mouseevent.y)**2
ind, = np.nonzero(np.less_equal(d, pixels**2))

print 'index is: ', str(ind)
return len(ind)>0,dict(ind=ind)

dates = [735079.1214674653, 735079.5, 735079.55647688662, 735079.60561398149, 735079.60901608795, 735079.61007837963, 735079.61141004635, 735079.61222394672, 735079.61267262732, 735079.61740547454, 735079.61793575226, 735079.61845732643, 735079.61902608792, 735079.68499270838, 735079.68542109954, 735079.68880315975, 735079.68926655094, 735079.68966354162, 735079.69596565969, 735079.701868125, 735079.70749983797, 735079.70960563654, 735079.71045478014, 735079.71102318284, 735079.71184613428, 735079.71230732638, 735079.71268356487, 735079.71303708339, 735079.71386268514, 735079.71445497684, 735079.715345, 735079.71684614581, 735079.7183792477, 735079.71955292823, 735079.72024780093, 735079.72192891198, 735079.72248410876, 735079.72560098383, 735079.72600572917, 735079.72638543986, 735079.72990056709, 735079.7316829, 735079.73226472223, 735079.73661531252, 735079.74144714116, 735079.74522572919, 735079.7468240856, 735079.74791210645, 735079.97846979171, 735079.98271479167, 735079.98447646992, 735080.12350728014, 735080.14091008098, 735080.55523804401, 735080.56125733792, 735080.63896374998, 735080.64021659724, 735080.64103072917, 735080.66268849536, 735080.7048011343, 735080.79961501155, 735080.86546409724, 735080.99817599542, 735081.0204026273, 735081.02133151621, 735081.02613285882, 735081.0271783449, 735081.0335956713, 735081.04115539347, 735081.04800446762, 735081.05008083337, 735081.05534546298, 735081.05918304401, 735081.06037712959, 735081.06172269676, 735081.06712594908, 735081.08196986106, 735081.62065618054, 735081.8688092361, 735081.86910491902, 735081.86998233793, 735081.99360535876, 735081.99586380785, 735082.00806468748, 735082.0098228819, 735082.01533834497, 735082.01674383099, 735082.02936186339, 735082.02976707171, 735082.03022675926, 735082.03069490741, 735082.03097482643, 735082.03125312505, 735082.03604334488, 735082.03765619209, 735082.05257208331, 735082.100969919, 735082.1024177199, 735082.10387097218, 735082.1388320023, 735082.337, 735082.53595807869, 735082.55833702546, 735082.56112760422, 735083.00588994217, 735083.007571875, 735113.50807679398, 735113.58693798608, 735114.03848809027, 735114.04119372682, 735115.5, 735119.8093059028, 735120.03856688656, 735253.07588778937, 735256.95615627314, 735258.69064364582, 735258.69268998841, 735258.69969299773, 735258.72694862273, 735259.62416826386, 735259.6248413, 735259.7361906945, 735259.75713817135, 735259.99948642356, 735260.00099298614, 735260.00174059032, 735260.00592855329, 735260.00680168986, 735260.00748263893, 735260.00827880786, 735260.00860694447, 735260.00958392362, 735260.02752453706, 735260.06593625003, 735260.07891475689, 735260.07907957176, 735260.07935114589, 735260.62010422454, 735260.62646800932, 735260.62662517361, 735260.66605687502, 735260.67675605323, 735260.68322124996, 735260.68342049769, 735260.68355356483, 735260.68561972224, 735260.68846386578, 735269.73599923612, 735285.60832390049, 735302.07172445604, 735304.07737268519, 735304.3925347,

Re: [Matplotlib-users] event.ind in point picking gives wrong number

2014-06-07 Thread C M
On Sat, Jun 7, 2014 at 4:02 PM, Benjamin Root  wrote:

> Thanks for the example script. I think I have a clue now what is happening.
>

Thank you for the quick reply.


> If one were to also print out the length of the "d" array, you will find
> that it is significantly shorter than when you aren't zoomed (I am getting
> a length of 7 when it should be 155). But it isn't truncated for the other
> dataset (which is of length 62). This makes me suspect that there is some
> threshold being triggered here (possibly around 128?).
>

I've tested it, and it seems that threshold number is 100.  If the dataset
has 100 points, the zooming doesn't affect the index.  If it has 101 or
more (I guess...I didn't test it in any comprehensive way), I get the
error.

I think at this point, you should definitely file a bug report.
>

 I have filed a bug report:

https://github.com/matplotlib/matplotlib/issues/3124

And I made it such that there is just the one data set and you can truncate
it to however many points you want, with the direction being to try 101
(which it is set to initially) and then try 100 or less.

Che
--
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their 
applications. Written by three acclaimed leaders in the field, 
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Re: [Matplotlib-users] event.ind in point picking gives wrong number

2014-06-07 Thread Benjamin Root
Thanks for the example script. I think I have a clue now what is happening.

If one were to also print out the length of the "d" array, you will find
that it is significantly shorter than when you aren't zoomed (I am getting
a length of 7 when it should be 155). But it isn't truncated for the other
dataset (which is of length 62). This makes me suspect that there is some
threshold being triggered here (possibly around 128?). I know there is such
a threshold for Paths for path simplification, but my tests turning it off
do not seem to make a difference. So, perhaps this might be related to
clipping?

I think at this point, you should definitely file a bug report.

Cheers!
Ben Root



On Sat, Jun 7, 2014 at 3:19 PM, C M  wrote:

> Hello again. This is follow-up on this 9 month old thread (I left this
> issue for a while and am now returning to it).
>
> I upgraded to the latest stable version of Matplotlib, 1.3.1, and tested
> and I am still getting the exact same confusing problem.
>
> Now I also have a small runnable test script that demonstrates this
> problem, from IDLE using Python 2.7 and Matplotlib 1.3.1.
>
> Attached is the script.  If you run it as is, it will show a plot. Click
> on the last point (which is obviously higher than the rest) and note the
> index number that is printed in the IDLE prompt.  It should say "index is:
> [154]".  But now zoom the plot tightly around that last point, and click on
> it again.  Now it will report that the index is much smaller (depending on
> how tightly you zoomed), down to "index is:  [1]".  This is the problem.
>
> What's critical to point out is:  this only occurs with *this* data.  To
> show that, go to the script and comment out the line near the end that
> starts with "plt.plot(bad_final_dates," and comment in the one below it,
> that starts with "plt.plot(good_final_dates,".  Run the script again, and
> repeat the process above.  You'll find that zooming does not affect the
> index number--which is the correct behavior.
>
> The contains_points() function was something I got on this mailing list
> from Jae-Joon some years back, and it is above my level of understanding,
> and it's possible I goofed something up in there.
>
> I'm really puzzled why one set of data doesn't have this problem and
> another one does. Any suggestions for what's wrong greatly appreciated.
>
> Thanks,
> Che
>
>
> On Mon, Sep 16, 2013 at 9:15 AM, Benjamin Root  wrote:
>
>>
>>
>>
>> On Sun, Sep 15, 2013 at 11:59 PM, C M  wrote:
>>
>>> Just a follow-up on this problem...
>>>
>>> I've found now that the index is only off if the plot is zoomed, and in
>>> the following way.  When I zoom, the first point that is visible in the
>>> plot window will have index = 0, the next point will have index = 1, and so
>>> forth.  If I zoom another section of the points, the indices are "reset" in
>>> this same way.
>>>
>>> What's really bizarre is that this is only occurring on one plot.  When
>>> I try to reproduce the problem on other plots (so far at least), I can't.
>>>
>>> Any suggestions for how to chase this down would be very welcome.
>>>
>>> Thanks.
>>>
>>>
>> That is a very useful observation. I am not very familiar with the artist
>> picking code, but if I have to guess, I would wonder if indices are being
>> determined from a path created *after* clip_to_rect() is used internally.
>> Given that you are having difficulties in reproducing this issue in other
>> plots, I would suggest trying to pare down your badly behaving code as much
>> as you can and post it here.  Furthermore, it would also be useful to
>> determine if the issue still occurs in v1.3 or in the master branch.
>>
>> Cheers!
>> Ben Root
>>
>
>
>
> --
> Learn Graph Databases - Download FREE O'Reilly Book
> "Graph Databases" is the definitive new guide to graph databases and their
> applications. Written by three acclaimed leaders in the field,
> this first edition is now available. Download your free book today!
> http://p.sf.net/sfu/NeoTech
> ___
> Matplotlib-users mailing list
> Matplotlib-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
>
--
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their 
applications. Written by three acclaimed leaders in the field, 
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/NeoTech___
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users


Re: [Matplotlib-users] event.ind in point picking gives wrong number

2014-06-07 Thread C M
Hello again. This is follow-up on this 9 month old thread (I left this
issue for a while and am now returning to it).

I upgraded to the latest stable version of Matplotlib, 1.3.1, and tested
and I am still getting the exact same confusing problem.

Now I also have a small runnable test script that demonstrates this
problem, from IDLE using Python 2.7 and Matplotlib 1.3.1.

Attached is the script.  If you run it as is, it will show a plot. Click on
the last point (which is obviously higher than the rest) and note the index
number that is printed in the IDLE prompt.  It should say "index is:
[154]".  But now zoom the plot tightly around that last point, and click on
it again.  Now it will report that the index is much smaller (depending on
how tightly you zoomed), down to "index is:  [1]".  This is the problem.

What's critical to point out is:  this only occurs with *this* data.  To
show that, go to the script and comment out the line near the end that
starts with "plt.plot(bad_final_dates," and comment in the one below it,
that starts with "plt.plot(good_final_dates,".  Run the script again, and
repeat the process above.  You'll find that zooming does not affect the
index number--which is the correct behavior.

The contains_points() function was something I got on this mailing list
from Jae-Joon some years back, and it is above my level of understanding,
and it's possible I goofed something up in there.

I'm really puzzled why one set of data doesn't have this problem and
another one does. Any suggestions for what's wrong greatly appreciated.

Thanks,
Che


On Mon, Sep 16, 2013 at 9:15 AM, Benjamin Root  wrote:

>
>
>
> On Sun, Sep 15, 2013 at 11:59 PM, C M  wrote:
>
>> Just a follow-up on this problem...
>>
>> I've found now that the index is only off if the plot is zoomed, and in
>> the following way.  When I zoom, the first point that is visible in the
>> plot window will have index = 0, the next point will have index = 1, and so
>> forth.  If I zoom another section of the points, the indices are "reset" in
>> this same way.
>>
>> What's really bizarre is that this is only occurring on one plot.  When I
>> try to reproduce the problem on other plots (so far at least), I can't.
>>
>> Any suggestions for how to chase this down would be very welcome.
>>
>> Thanks.
>>
>>
> That is a very useful observation. I am not very familiar with the artist
> picking code, but if I have to guess, I would wonder if indices are being
> determined from a path created *after* clip_to_rect() is used internally.
> Given that you are having difficulties in reproducing this issue in other
> plots, I would suggest trying to pare down your badly behaving code as much
> as you can and post it here.  Furthermore, it would also be useful to
> determine if the issue still occurs in v1.3 or in the master branch.
>
> Cheers!
> Ben Root
>

import matplotlib.pyplot as plt
import numpy as np

def contains_points(line, mouseevent):
line.pickradius = 5
# Make sure we have data to plot
if line._invalidy or line._invalidx:
line.recache()

if len(line._xy)==0: return False,{}

# Convert points to pixels
if line._transformed_path is None:
   line._transform_path()
path, affine = line._transformed_path.get_transformed_points_and_affine()
path = affine.transform_path(path)
xy = path.vertices
xt = xy[:, 0]
yt = xy[:, 1]

pixels = line.figure.dpi/72. * line.pickradius

d = (xt-mouseevent.x)**2 + (yt-mouseevent.y)**2
ind, = np.nonzero(np.less_equal(d, pixels**2))

print 'index is: ', str(ind)

return len(ind)>0,dict(ind=ind)

bad_final_dates = [735079.1214674653, 735079.5, 735079.55647688662, 735079.60561398149, 735079.60901608795, 735079.61007837963, 735079.61141004635, 735079.61222394672, 735079.61267262732, 735079.61740547454, 735079.61793575226, 735079.61845732643, 735079.61902608792, 735079.68499270838, 735079.68542109954, 735079.68880315975, 735079.68926655094, 735079.68966354162, 735079.69596565969, 735079.701868125, 735079.70749983797, 735079.70960563654, 735079.71045478014, 735079.71102318284, 735079.71184613428, 735079.71230732638, 735079.71268356487, 735079.71303708339, 735079.71386268514, 735079.71445497684, 735079.715345, 735079.71684614581, 735079.7183792477, 735079.71955292823, 735079.72024780093, 735079.72192891198, 735079.72248410876, 735079.72560098383, 735079.72600572917, 735079.72638543986, 735079.72990056709, 735079.7316829, 735079.73226472223, 735079.73661531252, 735079.74144714116, 735079.74522572919, 735079.7468240856, 735079.74791210645, 735079.97846979171, 735079.98271479167, 735079.98447646992, 735080.12350728014, 735080.14091008098, 735080.55523804401, 735080.56125733792, 735080.63896374998, 735080.64021659724, 735080.64103072917, 735080.66268849536, 735080.7048011343, 735080.79961501155, 735080.86546409724, 735080.99817599542, 735081.0204026273, 735081.02133151621, 735081.02613285882, 735081.0271783449, 735081.0335956713