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/
