## Re: [Matplotlib-users] Question on LineCollection

 Re: [Matplotlib-users] Question on LineCollection From: Justin McCann - 2011-07-13 19:32:40 2011/7/13 SULSEUNG-JIN : > Hi, > > I'm plotting thousands of short lines on a plot. Because "plot" and "Line2D" > are quite slow for this case, I'm trying to use lineCollection. Here comes > the part of my testing code: > >     ... >     segs = [] > >     # Manual set for testing >     x2 = np.zeros(2,dtype=int) >     ys2 = [np.zeros(2,dtype=float)] >     x2[0] = 1000000 >     x2[1] = 2000000 >     ys2[0][0] = ys2[0][1] = 50 >     segs.extend( [zip(x2,y) for y in ys2] ) > >     for i in range(0, len(records)): >         ... >         # get xStart, xEnd, and y >         ... > >         x2[0] = xStart >         x2[1] = xEnd >         ys2[0][0] = ys2[0][1] = y >         segs.extend( [zip(x2,y) for y in ys2] ) > >     line_segments = LineCollection(segs, linewidth=4, alpha=0.3, colors = > 'r', linestyle = 'solid') >     ax.add_collection(line_segments) >     ... > > The problem I have is only the first segment of the lines in the "segs" > which I manually set the values is shown in the plot. If I move the first > part in the for loop to test, it works. What am I missing? > > Thank you in advance. Are you sure it's the first segment that shows up, and not the last one? You're reusing the numpy array x2 and the list ys2. You're overwriting the values inside them each time through the for loop, but segs just contains len(records) references to the exact same arrays in memory (x2 and ys2). The reason it works if you move the first part inside is that it creates a new numpy.array x2 and a new python list ys2 each time then, which is what you want. Justin

 [Matplotlib-users] Question on LineCollection From: SULSEUNG-JIN - 2011-07-13 17:19:23 Attachments: Message as HTML Hi, I'm plotting thousands of short lines on a plot. Because "plot" and "Line2D" are quite slow for this case, I'm trying to use lineCollection. Here comes the part of my testing code: ... segs = [] # Manual set for testing x2 = np.zeros(2,dtype=int) ys2 = [np.zeros(2,dtype=float)] x2[0] = 1000000 x2[1] = 2000000 ys2[0][0] = ys2[0][1] = 50 segs.extend( [zip(x2,y) for y in ys2] ) for i in range(0, len(records)): ... # get xStart, xEnd, and y ... x2[0] = xStart x2[1] = xEnd ys2[0][0] = ys2[0][1] = y segs.extend( [zip(x2,y) for y in ys2] ) line_segments = LineCollection(segs, linewidth=4, alpha=0.3, colors = 'r', linestyle = 'solid') ax.add_collection(line_segments) ... The problem I have is only the first segment of the lines in the "segs" which I manually set the values is shown in the plot. If I move the first part in the for loop to test, it works. What am I missing? Thank you in advance. Jin ---
 Re: [Matplotlib-users] Question on LineCollection From: Justin McCann - 2011-07-13 19:32:40 2011/7/13 SULSEUNG-JIN : > Hi, > > I'm plotting thousands of short lines on a plot. Because "plot" and "Line2D" > are quite slow for this case, I'm trying to use lineCollection. Here comes > the part of my testing code: > >     ... >     segs = [] > >     # Manual set for testing >     x2 = np.zeros(2,dtype=int) >     ys2 = [np.zeros(2,dtype=float)] >     x2[0] = 1000000 >     x2[1] = 2000000 >     ys2[0][0] = ys2[0][1] = 50 >     segs.extend( [zip(x2,y) for y in ys2] ) > >     for i in range(0, len(records)): >         ... >         # get xStart, xEnd, and y >         ... > >         x2[0] = xStart >         x2[1] = xEnd >         ys2[0][0] = ys2[0][1] = y >         segs.extend( [zip(x2,y) for y in ys2] ) > >     line_segments = LineCollection(segs, linewidth=4, alpha=0.3, colors = > 'r', linestyle = 'solid') >     ax.add_collection(line_segments) >     ... > > The problem I have is only the first segment of the lines in the "segs" > which I manually set the values is shown in the plot. If I move the first > part in the for loop to test, it works. What am I missing? > > Thank you in advance. Are you sure it's the first segment that shows up, and not the last one? You're reusing the numpy array x2 and the list ys2. You're overwriting the values inside them each time through the for loop, but segs just contains len(records) references to the exact same arrays in memory (x2 and ys2). The reason it works if you move the first part inside is that it creates a new numpy.array x2 and a new python list ys2 each time then, which is what you want. Justin
 Re: [Matplotlib-users] Question on LineCollection From: SULSEUNG-JIN - 2011-07-13 20:13:58 Attachments: Message as HTML Thanks, Justin I think I made a confusing example code. Here comes new one: segs = [] for i in range(0, len(vec)): x1 = vec[i][0] #x1 = 3000000 x2 = vec[i][1] #x2 = 4000000 y1 = y2 = vec[i][2] segs.extend( [[(x1,y1),(x2,y2)]] ) line_segments = LineCollection(segs, linewidth=3, alpha=0.3, colors = 'r', linestyle = 'solid') ax.add_collection(line_segments) The above code doesn't show any lines. But if I comment out one or both of commented parts, the lines are shown. I mean the below cases are all work. x1 = vec[i][0] x2 = 4000000 y1 = y2 = vec[i][2] or x1 = 3000000 x2 = vec[i][1] y1 = y2 = vec[i][2] I think it's wierd. I'm pretty sure that the 2D array has valid values. Jin --- > Date: Wed, 13 Jul 2011 15:32:33 -0400 > Subject: Re: [Matplotlib-users] Question on LineCollection > From: jneilm@... > To: sulsj0270@... > CC: matplotlib-users@... > > 2011/7/13 SULSEUNG-JIN : > > Hi, > > > > I'm plotting thousands of short lines on a plot. Because "plot" and "Line2D" > > are quite slow for this case, I'm trying to use lineCollection. Here comes > > the part of my testing code: > > > > ... > > segs = [] > > > > # Manual set for testing > > x2 = np.zeros(2,dtype=int) > > ys2 = [np.zeros(2,dtype=float)] > > x2[0] = 1000000 > > x2[1] = 2000000 > > ys2[0][0] = ys2[0][1] = 50 > > segs.extend( [zip(x2,y) for y in ys2] ) > > > > for i in range(0, len(records)): > > ... > > # get xStart, xEnd, and y > > ... > > > > x2[0] = xStart > > x2[1] = xEnd > > ys2[0][0] = ys2[0][1] = y > > segs.extend( [zip(x2,y) for y in ys2] ) > > > > line_segments = LineCollection(segs, linewidth=4, alpha=0.3, colors = > > 'r', linestyle = 'solid') > > ax.add_collection(line_segments) > > ... > > > > The problem I have is only the first segment of the lines in the "segs" > > which I manually set the values is shown in the plot. If I move the first > > part in the for loop to test, it works. What am I missing? > > > > Thank you in advance. > > Are you sure it's the first segment that shows up, and not the last one? > > You're reusing the numpy array x2 and the list ys2. You're overwriting > the values inside them each time through the for loop, but segs just > contains len(records) references to the exact same arrays in memory > (x2 and ys2). > > The reason it works if you move the first part inside is that it > creates a new numpy.array x2 and a new python list ys2 each time then, > which is what you want. > > Justin
 Re: [Matplotlib-users] Question on LineCollection From: Justin McCann - 2011-07-13 20:44:08 2011/7/13 SULSEUNG-JIN : > Thanks, Justin > > I think I made a confusing example code. Here comes new one: Maybe you just need to force a call to draw() and set your x/y limits. This works for me on matplotlib 1.0.1 \$ ipython -pylab # ==== from matplotlib.collections import LineCollection f = figure() plot() ax = gca() vec = numpy.random.random((10,3)) segs = [] for i in range(0, len(vec)): x1 = vec[i][0] #x1 = 3000000 x2 = vec[i][1] #x2 = 4000000 y1 = y2 = vec[i][2] segs.extend( [[(x1,y1),(x2,y2)]] ) line_segments = LineCollection(segs, linewidth=3, alpha=0.3, colors = 'r', linestyle = 'solid') ax.add_collection(line_segments) ax.set_xlim(0,1) ax.set_ylim(0,1) show() # hmmmm... nothing yet draw() # force a draw; now it works
 Re: [Matplotlib-users] Question on LineCollection From: SULSEUNG-JIN - 2011-07-13 21:10:08 Attachments: Message as HTML Justin, your code works flawlessly. Well, I've got the "vec" from pytables like: vec = [ [x['sStart'],x['sEnd'],x['dIdent'],x['gi'] ] for x in table.where('(gi == currGi) & (sId == currSubId)') ] With the above "vec", it does not work. Do you have any idea? Jin. --- > Date: Wed, 13 Jul 2011 16:44:01 -0400 > Subject: Re: [Matplotlib-users] Question on LineCollection > From: jneilm@... > To: sulsj0270@... > CC: matplotlib-users@... > > 2011/7/13 SULSEUNG-JIN : > > Thanks, Justin > > > > I think I made a confusing example code. Here comes new one: > > Maybe you just need to force a call to draw() and set your x/y limits. > This works for me on matplotlib 1.0.1 > > \$ ipython -pylab > # ==== > from matplotlib.collections import LineCollection > f = figure() > plot() > ax = gca() > vec = numpy.random.random((10,3)) > segs = [] > for i in range(0, len(vec)): > x1 = vec[i][0] > #x1 = 3000000 > x2 = vec[i][1] > #x2 = 4000000 > y1 = y2 = vec[i][2] > segs.extend( [[(x1,y1),(x2,y2)]] ) > > line_segments = LineCollection(segs, linewidth=3, alpha=0.3, colors = > 'r', linestyle = 'solid') > ax.add_collection(line_segments) > ax.set_xlim(0,1) > ax.set_ylim(0,1) > show() # hmmmm... nothing yet > draw() # force a draw; now it works
 Re: [Matplotlib-users] Question on LineCollection From: SULSEUNG-JIN - 2011-07-13 22:31:35 Attachments: Message as HTML If I set like vec = 100*numpy.random.random((10,3)) it does not shpw lines even with changing the set_xlimit and set_ylimit. I guess there is something related with scaling. Jin --- > Date: Wed, 13 Jul 2011 16:44:01 -0400 > Subject: Re: [Matplotlib-users] Question on LineCollection > From: jneilm@... > To: sulsj0270@... > CC: matplotlib-users@... > > 2011/7/13 SULSEUNG-JIN : > > Thanks, Justin > > > > I think I made a confusing example code. Here comes new one: > > Maybe you just need to force a call to draw() and set your x/y limits. > This works for me on matplotlib 1.0.1 > > \$ ipython -pylab > # ==== > from matplotlib.collections import LineCollection > f = figure() > plot() > ax = gca() > vec = numpy.random.random((10,3)) > segs = [] > for i in range(0, len(vec)): > x1 = vec[i][0] > #x1 = 3000000 > x2 = vec[i][1] > #x2 = 4000000 > y1 = y2 = vec[i][2] > segs.extend( [[(x1,y1),(x2,y2)]] ) > > line_segments = LineCollection(segs, linewidth=3, alpha=0.3, colors = > 'r', linestyle = 'solid') > ax.add_collection(line_segments) > ax.set_xlim(0,1) > ax.set_ylim(0,1) > show() # hmmmm... nothing yet > draw() # force a draw; now it works
 Re: [Matplotlib-users] Question on LineCollection From: Benjamin Root - 2011-07-13 22:49:11 On Wednesday, July 13, 2011, Justin McCann wrote: > 2011/7/13 SULSEUNG-JIN : >> Thanks, Justin >> >> I think I made a confusing example code. Here comes new one: > > Maybe you just need to force a call to draw() and set your x/y limits. > This works for me on matplotlib 1.0.1 > > \$ ipython -pylab > # ==== > from matplotlib.collections import LineCollection > f = figure() > plot() > ax = gca() > vec = numpy.random.random((10,3)) > segs = [] > for i in range(0, len(vec)): >    x1 = vec[i][0] >    #x1 = 3000000 >    x2 = vec[i][1] >    #x2 = 4000000 >    y1 = y2 = vec[i][2] >    segs.extend( [[(x1,y1),(x2,y2)]] ) > > line_segments = LineCollection(segs, linewidth=3, alpha=0.3, colors = > 'r', linestyle = 'solid') > ax.add_collection(line_segments) > ax.set_xlim(0,1) > ax.set_ylim(0,1) > show() # hmmmm... nothing yet > draw() # force a draw; now it works > > ------------------------------------------------------------------------------ > AppSumo Presents a FREE Video for the SourceForge Community by Eric > Ries, the creator of the Lean Startup Methodology on "Lean Startup > Secrets Revealed." This video shows you how to validate your ideas, > optimize your ideas and identify your business strategy. > http://p.sf.net/sfu/appsumosfdev2dev > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users@... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > Just an observation (I haven't tested anything)... But what is up with the call to plot()? It might be causing issues with the autoscaler. Any line collections created without other plotting functions is going to need the axes limits set. Ben Root
 Re: [Matplotlib-users] Question on LineCollection From: Justin McCann - 2011-07-14 15:06:37 On Wed, Jul 13, 2011 at 6:49 PM, Benjamin Root wrote: > On Wednesday, July 13, 2011, Justin McCann wrote: >> \$ ipython -pylab >> # ==== >> from matplotlib.collections import LineCollection >> f = figure() >> plot() >> ax = gca() >> vec = numpy.random.random((10,3)) >> segs = [] >> for i in range(0, len(vec)): >>     x1 = vec[i][0] >>     #x1 = 3000000 >>     x2 = vec[i][1] >>     #x2 = 4000000 >>     y1 = y2 = vec[i][2] >>     segs.extend( [[(x1,y1),(x2,y2)]] ) >> >> line_segments = LineCollection(segs, linewidth=3, alpha=0.3, colors = >> 'r', linestyle = 'solid') >> ax.add_collection(line_segments) >> ax.set_xlim(0,1) >> ax.set_ylim(0,1) >> show() # hmmmm... nothing yet >> draw() # force a draw; now it works >> ... > Just an observation (I haven't tested anything)... But what is up with > the call to plot()?  It might be causing issues with the autoscaler. > Any line collections created without other plotting functions is going > to need the axes limits set. > > Ben Root > Yeah, that was weird. :) I added that when I was first messing around, and the axes didn't show up even when I called show(). If you do the draw() at the end, then you don't need to call plot(), and then you also don't need to mess with the view limits (set_{x,y}lim). I guess the moral of the story is, "if you don't explicitly plot() [or a variant], you must explicitly draw()." === from matplotlib.collections import LineCollection f = figure() ax = gca() vec = numpy.random.random((10,3)) segs = [] for i in range(0, len(vec)): x1 = vec[i][0] x2 = vec[i][1] y1 = y2 = vec[i][2] segs.extend( [[(x1,y1),(x2,y2)]] ) line_segments = LineCollection(segs, linewidth=3, alpha=0.3, colors='r', linestyle='solid') ax.add_collection(line_segments) draw() # force a draw; now it works ====