|
From: C M <cmp...@gm...> - 2014-06-08 02:12:33
Attachments:
how_to_modify_contains_points.py
|
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 |
|
From: Eric F. <ef...@ha...> - 2014-06-08 02:18:54
|
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 > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > |
|
From: C M <cmp...@gm...> - 2014-06-08 03:04:03
|
On Sat, Jun 7, 2014 at 10:18 PM, Eric Firing <ef...@ha...> 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 |
|
From: Eric F. <ef...@ha...> - 2014-06-08 04:10:10
|
On 2014/06/07, 5:03 PM, C M wrote: > > > > On Sat, Jun 7, 2014 at 10:18 PM, Eric Firing <ef...@ha... > <mailto:ef...@ha...>> 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 > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > |
|
From: C M <cmp...@gm...> - 2014-06-08 17:16:23
|
Great, thanks for all the help! On Sun, Jun 8, 2014 at 12:09 AM, Eric Firing <ef...@ha...> wrote: > On 2014/06/07, 5:03 PM, C M wrote: > > > > > > > > On Sat, Jun 7, 2014 at 10:18 PM, Eric Firing <ef...@ha... > > <mailto:ef...@ha...>> 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 > > Mat...@li... > > 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 > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > |