From: Paul C. <pau...@un...> - 2005-06-17 07:53:37
|
Forgot the previous message, I did a bad manipulation John, Sorry for the late answer but I had problems in designing a simple example ( I had the very bad idea to choose letter "l" as the key to press) and also lots of other things to do. Here it is : ############################################################################ from pylab import * def pick(event): if event.key=='p' and event.inaxes is not None: ax=event.inaxes a=ax.pick(event.x,event.y) a.set_color('g') a.set_linewidth(2.) draw() if event.key=='m' and event.inaxes is not None: ax=event.inaxes a=ax.pickBigLine(event.x,event.y) a.set_color('g') a.set_linewidth(2.) draw() ############################################################################ def PlotTwoLines(): plot([0.,0.],[-100.,100.]) plot([2.,2.],[-1.,1.]) connect('key_press_event',pick) xmin,xmax,ymin,ymax=axis() axis([xmin-1.,xmax+1.,ymin*1.1,ymax*1.1]) show() if __name__=='__main__': PlotTwoLines() ################################################################################# In this simple program, there is two way for picking a line, the classical pick method associated to the "p" key and PickBigLine method bassociated to the "m" key. The code just draw two lines a big one and a small one. The classical pick method works prefectly if you do not do a zoom to see the small line. But if you do it to see more accurately this small line then it is impossible to pick the big line unless you use PickBigLine. Basically, PickBigLine evaluates the orthogonal distance from the selected point to the line by calculating the intersection between the line you want to select and a line passing through the selected point which is orthogonal. Here is a modified version of PickBigLine taking into account your remarks and working with Matplotlib 0.82. -------------------------------------------------------------------------------------------------- def pickBigLine(self, x, y, trans=None): """ Return the Line artist under point that is closest to the x, y. if trans is None, x, and y are in window coords, 0,0 = lower left. Otherwise, trans is a matplotlib transform that specifies the coordinate system of x, y. Calculates the orthogonal distance to the line Note this algorithm calculates distance to the vertices of the polygon, so if you want to pick a patch, click on the edge! """ if trans is not None: xywin = trans.xy_tup((x,y)) else: xywin = x,y def dist(a): Cste=1.e6 xdata = a.get_xdata(valid_only = True) ydata = a.get_ydata(valid_only = True) # A point is not a line if len(xdata) == 1: return Cste xt, yt = a.get_transform().numerix_x_y(xdata, ydata) xc, yc = xt[1]-xt[0], yt[1]-yt[0] if (xc==0.0 and yc == 0.0): return Cste D = xc*xc + yc*yc D1 = -(xt[0]-xywin[0])*yc+(yt[0]-xywin[1])*xc D2 = -(yt[0]-xywin[1])*yc-(xt[0]-xywin[0])*xc if D2/D>1.00001 or D2/D<-0.00001: return Cste return abs(D1/sqrt(D)) artists = self.lines if not len(artists): return None ds = [ (dist(a),a) for a in artists] ds.sort() return ds[0][1] ------------------------------------------------------------------------------------ My interests are in ray tracing in geophysics. I am generating a lot of lines (thousands of) and then I need after zooming to identify trajectories connecting a source and a receiver . For example when I am picking a line I need to know to what beam it belongs and also to what ray it coresponds (two integers for instance) which is something I know when I am plotting the line. I don't know how to do it with the label property. It is an axes property not a line2D property. If you want I can give an example of the use of the tag property I add. Paul |
From: John H. <jdh...@ac...> - 2005-06-17 14:05:18
|
>>>>> "Paul" == Paul Cristini <pau...@un...> writes: Paul> you use PickBigLine. Basically, PickBigLine evaluates the Paul> orthogonal distance from the selected point to the line by Paul> calculating the intersection between the line you want to Paul> select and a line passing through the selected point which Paul> is orthogonal. Here is a modified version of PickBigLine Paul> taking into account your remarks and working with Matplotlib Paul> 0.82. Hi Paul, OK, at least now I understand what the problem is. The current Axes picker works on line vertices and not individual segments, so if you zoom in on a segment and click on it you may not be near any of the vertices. There is a similar problem with picking on polygons. Ideally, you want to iterate over all the segments in the lines and return the minimum distance to a segment (note there is a method matplotlib.mlab.dist_point_to_segment which computes this distance). For polygons, you would want to implement a test of insidedness. I thought about this when implementing the pick method but was afraid of the case when you have lots of segments; things could get really slow if you have a line with 10000 points unless you wrote some special purpose extension code. I do not think a separate "pick big line method" is needed here. Perhaps it makes more sense to add a flag to the pick method which either does it the correct and potentially slow way (useverts=False or something like that) or just picks on the vertices which is fast. For dense lines, picking on the vertices works fine, but as you note this condition isn't always true. Paul> My interests are in ray tracing in geophysics. I am Paul> generating a lot of lines (thousands of) and then I need Paul> after zooming to identify trajectories connecting a source Paul> and a receiver . For example when I am picking a line I need Paul> to know to what beam it belongs and also to what ray it Paul> coresponds (two integers for instance) which is something I Paul> know when I am plotting the line. I don't know how to do it Paul> with the label property. It is an axes property not a line2D Paul> property. If you want I can give an example of the use of Paul> the tag property I add. An example would help. Of course, in python, you can "tag" anything you want ax = subplot(111) ax.myinitials = 'JDH' line, = ax.plot([1,2,3]) line.mydata = ('Hi', 23) So it is questionable whether adding a "tag" attribute in particular is helpful. JDH |
From: Paul C. <pau...@un...> - 2005-06-17 15:00:45
|
John Hunter a =E9crit : >>>>>>"Paul" =3D=3D Paul Cristini <pau...@un...> writes: >>>>>> =20 >>>>>> > > Paul> you use PickBigLine. Basically, PickBigLine evaluates the > Paul> orthogonal distance from the selected point to the line by > Paul> calculating the intersection between the line you want to > Paul> select and a line passing through the selected point which > Paul> is orthogonal. Here is a modified version of PickBigLine > Paul> taking into account your remarks and working with Matplotlib > Paul> 0.82. > >Hi Paul,=20 > >OK, at least now I understand what the problem is. The current Axes >picker works on line vertices and not individual segments, so if you >zoom in on a segment and click on it you may not be near any of the >vertices. There is a similar problem with picking on polygons. >Ideally, you want to iterate over all the segments in the lines and >return the minimum distance to a segment (note there is a method >matplotlib.mlab.dist_point_to_segment which computes this distance). >For polygons, you would want to implement a test of insidedness.=20 > >I thought about this when implementing the pick method but was afraid >of the case when you have lots of segments; things could get really >slow if you have a line with 10000 points unless you wrote some >special purpose extension code. > >I do not think a separate "pick big line method" is needed here. >Perhaps it makes more sense to add a flag to the pick method which >either does it the correct and potentially slow way (useverts=3DFalse or >something like that) or just picks on the vertices which is fast. For >dense lines, picking on the vertices works fine, but as you note this >condition isn't always true. > > Paul> My interests are in ray tracing in geophysics. I am > Paul> generating a lot of lines (thousands of) and then I need > Paul> after zooming to identify trajectories connecting a source > Paul> and a receiver . For example when I am picking a line I need > Paul> to know to what beam it belongs and also to what ray it > Paul> coresponds (two integers for instance) which is something I > Paul> know when I am plotting the line. I don't know how to do it > Paul> with the label property. It is an axes property not a line2D > Paul> property. If you want I can give an example of the use of > Paul> the tag property I add. > >An example would help. > >Of course, in python, you can "tag" anything you want > > ax =3D subplot(111) > ax.myinitials =3D 'JDH' > > line, =3D ax.plot([1,2,3]) > line.mydata =3D ('Hi', 23) > >So it is questionable whether adding a "tag" attribute in particular >is helpful. > >JDH > > >------------------------------------------------------- >SF.Net email is sponsored by: Discover Easy Linux Migration Strategies >from IBM. Find simple to follow Roadmaps, straightforward articles, >informative Webcasts and more! Get everything you need to get up to >speed, fast. http://ads.osdn.com/?ad_id=3D7477&alloc_id=3D16492&op=3Dcli= ck >_______________________________________________ >Matplotlib-devel mailing list >Mat...@li... >https://lists.sourceforge.net/lists/listinfo/matplotlib-devel > =20 > You're right I did some tests taking into account your remarks and it works well. I agree the tag method is not helpfull and I can do without it. I also agree that a separate method for picking is not needed a flag just as you suggested will be enough. The mlab.dist_point_to_segment provides exactly the same results as what I wrote in the PickBigLine. Thanks a lot for your advices Paul |
From: John H. <jdh...@ac...> - 2005-06-17 14:06:39
|
Paul> The code just draw two lines a big one and a small one. The Paul> classical pick method works prefectly if you do not do a Paul> zoom to see the small line. But if you do it to see more Paul> accurately this small line then it is impossible to pick the Paul> big line unless you use PickBigLine. Basically, PickBigLine Paul> evaluates the orthogonal distance from the selected point to Paul> the line by calculating the intersection between the line Paul> you want to select Hi Paul, OK, at least now I understand what the problem is. The current Axes picker works on line vertices and not individual segments, so if you zoom in on a segment and click on it you may not be near any of the vertices. There is a similar problem with picking on polygons. Ideally, you want to iterate over all the segments in the lines and return the minimum distance to a segment (note there is a method matplotlib.mlab.dist_point_to_segment which computes this distance). For polygons, you would want to implement a test of insidedness. I thought about this when implementing the pick method but was afraid of the case when you have lots of segments; things could get really slow if you have a line with 10000 points unless you wrote some special purpose extension code. I do not think a separate "pick big line method" is needed here. Perhaps it makes more sense to add a flag to the pick method which either does it the correct and potentially slow way (useverts=False or something like that) or just picks on the vertices which is fast. For dense lines, picking on the vertices works fine, but as you note this condition isn't always true. Paul> My interests are in ray tracing in geophysics. I am Paul> generating a lot of lines (thousands of) and then I need Paul> after zooming to identify trajectories connecting a source Paul> and a receiver . For example when I am picking a line I need Paul> to know to what beam it belongs and also to what ray it Paul> coresponds (two integers for instance) which is something I Paul> know when I am plotting the line. I don't know how to do it Paul> with the label property. It is an axes property not a line2D Paul> property. If you want I can give an example of the use of Paul> the tag property I add. An example would help. Of course, in python, you can "tag" anything you want ax = subplot(111) ax.myinitials = 'JDH' line, = ax.plot([1,2,3]) line.mydata = ('Hi', 23) So it is questionable whether adding a "tag" attribute in particular is helpful. JDH |