From: <bfb...@ya...> - 2005-05-29 03:15:50
Attachments:
plot_map_problem.tar.gz
|
Hello, Can anybody help me with turning on clipping when stroking world coast outlines in a graph? I attach the script + data, but if it does not get thru, here is a summary: g = graph.graphxy(height=8, width=16, x=graph.axis.linear(min=lonmin, max=lonmax, title=r'$\lambda$'), y=graph.axis.linear(min=latmin, max=latmax, title=r'$\phi$')) for a in lines: p = path.path(path.moveto(a[0],a[1])) for i in range(2,len(a),2): p.append(path.lineto(a[i],a[i+1])) p=p.transformed(tt) g.stroke(p) -Brian |
From: Andre W. <wo...@us...> - 2005-06-01 16:05:31
|
Hi, On 28.05.05, bfb...@ya... wrote: > Hello, > > Can anybody help me with turning on clipping > when stroking world coast outlines in a graph? > > I attach the script + data, but if it does not get thru, > here is a summary: > > g = graph.graphxy(height=8, width=16, > x=graph.axis.linear(min=lonmin, max=lonmax, title=r'$\lambda$'), > y=graph.axis.linear(min=latmin, max=latmax, title=r'$\phi$')) > > for a in lines: > p = path.path(path.moveto(a[0],a[1])) > for i in range(2,len(a),2): > p.append(path.lineto(a[i],a[i+1])) > p=p.transformed(tt) > g.stroke(p) The point is, that graph canvases do not clip. We do not even (any more) clip the regular graph content, since this could clip parts of symbols and parts of the line when they "touch" the border. But this is out of scope for you. You could use a line-like graph style for plotting your map (actually, this would be a really nice feature) and use the clip calculation of the existing grpah line style. But this is not what you asked for. Its actually much easier. You can create a canvas which clips its content to a given path. Your example would become: #!/usr/bin/env python from pyx import * import cPickle # Plot a map and plot data points inp=open('world_coast.pickle','r') stuff=cPickle.load(inp) lines=stuff['lines'] heads=stuff['heads'] inp.close() lonmin=-180. lonmax=180. latmin=-90. latmax=90. #uncomment the following two line to show the problem lonmax=0. latmax=0. g = graph.graphxy(height=8, width=16, x=graph.axis.linear(min=lonmin, max=lonmax, title=r'$\lambda$'), y=graph.axis.linear(min=latmin, max=latmax, title=r'$\phi$')) #clipping happens on these three points: a=[[-50,-60],[-40,-60],[30,-50]] g.plot(graph.data.list(a, x=1, y=2), [graph.style.symbol(graph.style.symbol.circle, size=0.5, symbolattrs=[deco.filled([color.rgb.green]), deco.stroked([color.rgb.red])])]) xmin,ymin=g.pos(lonmin,latmin) xmax,ymax=g.pos(lonmax,latmax) sx=(xmax-xmin)/(lonmax-lonmin) sy=(ymax-ymin)/(latmax-latmin) #tt=trafo.translate(-lonmin,-latmin) #note "translate", not "translated" #tt=tt.scaled(sx) #note "scaled", not "scale" #plot the map, notice problem with clipping c = canvas.canvas([canvas.clip(path.rect(g.xpos, g.ypos, g.width, g.height)), trafo.scale(sx), trafo.translate(-lonmin,-latmin)]) g.insert(c) for a in lines: p = path.path(path.moveto(a[0],a[1])) for i in range(2,len(a),2): p.append(path.lineto(a[i],a[i+1])) #p=p.transformed(tt) c.stroke(p) g.writeEPSfile('plot_map') Note, that I also applied the transformation to the canvas, such that you can stroke the untransformed lines to the canvas. Note, finally, that a graph is nothing more like an ordinary canvas and we insert your clipping canvas into that graph canvas. I hope I could give you some hints/advices ... André -- by _ _ _ Dr. André Wobst / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript figures with Python & TeX (_/ \_)_/\_/ visit http://pyx.sourceforge.net/ |
From: <bfb...@ya...> - 2005-06-02 08:51:18
|
Thanks! That certainly works. Your reply indicates there is an easier way to do this. I would be grateful if you could show me. I would also like to be able to plot other primitives, such as colored triangles and polygons, beneath the map. -Brian --- Andre Wobst <wo...@us...> wrote: > Hi, > > On 28.05.05, bfb...@ya... wrote: > > Hello, > > > > Can anybody help me with turning on clipping > > when stroking world coast outlines in a graph? > > > > I attach the script + data, but if it does not get thru, > > here is a summary: > > > > g = graph.graphxy(height=8, width=16, > > x=graph.axis.linear(min=lonmin, max=lonmax, title=r'$\lambda$'), > > y=graph.axis.linear(min=latmin, max=latmax, title=r'$\phi$')) > > > > for a in lines: > > p = path.path(path.moveto(a[0],a[1])) > > for i in range(2,len(a),2): > > p.append(path.lineto(a[i],a[i+1])) > > p=p.transformed(tt) > > g.stroke(p) > > The point is, that graph canvases do not clip. We do not even (any > more) clip the regular graph content, since this could clip parts of > symbols and parts of the line when they "touch" the border. But this > is out of scope for you. > > You could use a line-like graph style for plotting your map (actually, > this would be a really nice feature) and use the clip calculation of > the existing grpah line style. But this is not what you asked for. Its > actually much easier. You can create a canvas which clips its content > to a given path. Your example would become: > > #!/usr/bin/env python > from pyx import * > import cPickle > # Plot a map and plot data points > > inp=open('world_coast.pickle','r') > stuff=cPickle.load(inp) > lines=stuff['lines'] > heads=stuff['heads'] > inp.close() > > lonmin=-180. > lonmax=180. > latmin=-90. > latmax=90. > #uncomment the following two line to show the problem > lonmax=0. > latmax=0. > g = graph.graphxy(height=8, width=16, > x=graph.axis.linear(min=lonmin, max=lonmax, title=r'$\lambda$'), > y=graph.axis.linear(min=latmin, max=latmax, title=r'$\phi$')) > #clipping happens on these three points: > a=[[-50,-60],[-40,-60],[30,-50]] > g.plot(graph.data.list(a, x=1, y=2), > [graph.style.symbol(graph.style.symbol.circle, size=0.5, > symbolattrs=[deco.filled([color.rgb.green]), > deco.stroked([color.rgb.red])])]) > xmin,ymin=g.pos(lonmin,latmin) > xmax,ymax=g.pos(lonmax,latmax) > sx=(xmax-xmin)/(lonmax-lonmin) > sy=(ymax-ymin)/(latmax-latmin) > #tt=trafo.translate(-lonmin,-latmin) #note "translate", not "translated" > #tt=tt.scaled(sx) #note "scaled", not "scale" > #plot the map, notice problem with clipping > c = canvas.canvas([canvas.clip(path.rect(g.xpos, g.ypos, g.width, g.height)), > trafo.scale(sx), > trafo.translate(-lonmin,-latmin)]) > g.insert(c) > for a in lines: > p = path.path(path.moveto(a[0],a[1])) > for i in range(2,len(a),2): > p.append(path.lineto(a[i],a[i+1])) > #p=p.transformed(tt) > c.stroke(p) > g.writeEPSfile('plot_map') > > Note, that I also applied the transformation to the canvas, such that > you can stroke the untransformed lines to the canvas. Note, finally, > that a graph is nothing more like an ordinary canvas and we insert > your clipping canvas into that graph canvas. > > I hope I could give you some hints/advices ... > > > André > > -- > by _ _ _ Dr. André Wobst > / \ \ / ) wo...@us..., http://www.wobsta.de/ > / _ \ \/\/ / PyX - High quality PostScript figures with Python & TeX > (_/ \_)_/\_/ visit http://pyx.sourceforge.net/ > > > ------------------------------------------------------- > This SF.Net email is sponsored by Yahoo. > Introducing Yahoo! Search Developer Network - Create apps using Yahoo! > Search APIs Find out how you can build Yahoo! directly into your own > Applications - visit http://developer.yahoo.net/?fr=offad-ysdn-ostg-q22005 > _______________________________________________ > PyX-user mailing list > PyX...@li... > https://lists.sourceforge.net/lists/listinfo/pyx-user > |
From: Andre W. <wo...@us...> - 2005-06-02 09:38:14
|
Hi, On 01.06.05, bfb...@ya... wrote: > Thanks! That certainly works. Your reply indicates > there is an easier way to do this. I would be grateful > if you could show me. Well, as I said, the graph styles usually take care of clipping the content to graph area themself. Since you basically want to stroke some lines, you can use a single plot-a-line statement and prepare the data accordingly. (You can insert an invalid point to separete several paths and the line style will take care of plotting those paths separetely. Alternatively you could do several plot-line-statements for each line disabling the interation over the line styles.) In the end this will look like: #!/usr/bin/env python from pyx import * import cPickle inp=open('world_coast.pickle','r') stuff=cPickle.load(inp) lines=stuff['lines'] heads=stuff['heads'] inp.close() points = [] for coords in lines: points.extend(zip(coords[::2], coords[1::2])) # mark new segments by an invalid point points.append((None, None)) g = graph.graphxy(height=8, width=16, x=graph.axis.linear(min=-90, max=90, title=r'$\lambda$'), y=graph.axis.linear(min=0, max=90, title=r'$\phi$')) g.plot(graph.data.list(points, x=1, y=2), [graph.style.line()]) g.writeEPSfile('plot_map') Note that in the resulting output only those parts of the map are inserted, which are actually visible. That's because the style handles the clipping. > I would also like to be able > to plot other primitives, such as colored triangles and > polygons, beneath the map. As you already found out, you can stroke yourself onto the graph canvas. As I show you in my previous posting, you can use the PostScript clipping functionality by inserting a canvas with a clipping path set. Doesn't this solve your problem? May I do not fully understand your problem. Feel free to explain. André -- by _ _ _ Dr. André Wobst / \ \ / ) wo...@us..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript figures with Python & TeX (_/ \_)_/\_/ visit http://pyx.sourceforge.net/ |