## pyx-user

 [PyX-user] Gradient according to external data file From: Mico Filós - 2010-10-27 14:35:02 ```Hi all, I've looked around. but I haven't found the solution to the following problem: I have an array containing N points (x, y, r), where x is an abscissa, y is an ordinate, and r is a real between 0 and 1. I would like to plot the the array {(x, y)} as a continuous path, using the sequence of r's as the normalized gray value at each particular point. This is not hard if data points are plotted with symbols, but I want to use the line style for data points, taking the sequence of N r's as the (externally defined) color gradient for the curve defined by {(x, y)}. It sounds more complicated than it really is. Any ideas? Thanks a lot for your help. Mico ```
 Re: [PyX-user] Gradient according to external data file From: Stefan Schenk - 2010-10-27 19:11:43 ```Hi Mico, Am Mittwoch, 27. Oktober 2010, 16:34:56 schrieb Mico Filós: > I have an array containing N points (x, y, r), where x is an > abscissa, y is an ordinate, and r is a real between 0 and 1. I would > like to plot the the array {(x, y)} as a continuous path, using the > sequence of r's as the normalized gray value at each particular > point. This is not hard if data points are plotted with symbols, > but I want to use the line style for data points, taking the > sequence of N r's as the (externally defined) color gradient for > the curve defined by {(x, y)}. > It sounds more complicated than it really is. Any ideas? I don't see an easy way to do this. What makes this even more complex is that with lines your third dimension (r) is not well defined. For points you can always assign a color to the point, but a line lives between two points. What color do you assign to the line? Of course there are complicated ways to do something like this: The most straightforward way I can think of at the moment is to create the paths between the points by hand, then splitting these paths and then drawing each of these subpaths with colors according to the colors at your points. HTH, Stefan ```
 Re: [PyX-user] Gradient according to external data file From: André Wobst - 2010-10-27 19:59:22 Attachments: smime.p7s ```Am 27.10.2010 um 21:10 schrieb Stefan Schenk: > Am Mittwoch, 27. Oktober 2010, 16:34:56 schrieb Mico Filós: >> I have an array containing N points (x, y, r), where x is an >> abscissa, y is an ordinate, and r is a real between 0 and 1. I would >> like to plot the the array {(x, y)} as a continuous path, using the >> sequence of r's as the normalized gray value at each particular >> point. This is not hard if data points are plotted with symbols, >> but I want to use the line style for data points, taking the >> sequence of N r's as the (externally defined) color gradient for >> the curve defined by {(x, y)}. >> It sounds more complicated than it really is. Any ideas? > > I don't see an easy way to do this. What makes this even more complex is > that with lines your third dimension (r) is not well defined. For points > you can always assign a color to the point, but a line lives between two > points. What color do you assign to the line? > > Of course there are complicated ways to do something like this: > The most straightforward way I can think of at the moment is to create > the paths between the points by hand, then splitting these paths and > then drawing each of these subpaths with colors according to the colors > at your points. You are right, Stefan. I'm not aware of a possibility to alter the color of a line either. However, we can go along the line of splitting the each line manually and alter the color as needed. And, this is PyX, where you can introduce such a graph style by just a couple of lines. Here we go: -------------------- from pyx import * class gradientline(graph.style.line): def __init__(self, colorcolumnname="color", colorprecision=100, gradient=color.gradient.Gray, **kwargs): self.colorcolumnname = colorcolumnname self.colorprecision = colorprecision self.gradient = gradient graph.style.line.__init__(self, **kwargs) def columnnames(self, privatedata, sharedata, agraph, columnnames): if self.colorcolumnname not in columnnames: raise ValueError("column '%s' missing" % self.colorcolumnname) return ([self.colorcolumnname] + graph.style.line.columnnames(self, privatedata, sharedata, agraph, columnnames)) def initdrawpoints(self, privatedata, sharedata, graph): privatedata.color = None def drawpoint(self, privatedata, sharedata, graph, point): if privatedata.color is not None: self.addpoint(privatedata, graph.vpos_pt, sharedata.vposavailable, sharedata.vposvalid, sharedata.vpos) path = self.donepointstopath(privatedata) if privatedata.lineattrs is not None and len(path): splits = int(abs(point[self.colorcolumnname] - privatedata.color)*self.colorprecision) if splits: path = path.normpath() arclen_pt = path.arclen_pt() segments = path.split_pt([(i+1)*arclen_pt/(splits+1) for i in range(splits)]) for i, segment in enumerate(segments): graph.stroke(segment, privatedata.lineattrs + [self.gradient.getcolor(privatedata.color + (point[self.colorcolumnname]-privatedata.color)*(i+0.5)/splits)]) else: graph.stroke(path, privatedata.lineattrs + [self.gradient.getcolor(point[self.colorcolumnname])]) self.initpointstopath(privatedata) self.addpoint(privatedata, graph.vpos_pt, sharedata.vposavailable, sharedata.vposvalid, sharedata.vpos) privatedata.color = point[self.colorcolumnname] def donedrawpoints(self, privatedata, sharedata, graph): pass g = graph.graphxy(width=10) g.plot(graph.data.points([[random.random() for i in range(3)] for i in range(10)], x=1, y=2, color=3), [gradientline(gradient=color.gradient.Rainbow)]) g.writePDFfile() -------------------- André -- by _ _ _ Dr. André Wobst, Amselweg 22, 85716 Unterschleißheim / \ \ / ) wobsta@..., http://www.wobsta.de/ / _ \ \/\/ / PyX - High quality PostScript and PDF figures (_/ \_)_/\_/ with Python & TeX: visit http://pyx.sourceforge.net/ ```
 Re: [PyX-user] Gradient according to external data file From: Mico Filós - 2010-10-28 19:07:59 ```Thanks a lot Stefan and André for your quick and valuable answers. André's snippet does perfectly the job! ```