From 59ed8dd2340023964f388dc9ec4c3c741b626298 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B6rg=20Lehmann?= Date: Tue, 20 Jun 2006 11:45:54 +0000 Subject: [PATCH] - renamed: palette->gradient, functionpalette->functiongradient, linearpalette->lineargradient - new class palette representing a discrete ordered list of colors git-svn-id: https://pyx.svn.sourceforge.net/svnroot/pyx/trunk/pyx@2828 069f4177-920e-0410-937b-c2a4a81bcd90 --- CHANGES | 7 ++- examples/graphs/change.py | 2 +- examples/graphs/change.txt | 8 +-- examples/graphstyles/changesymbol.py | 6 +-- gallery/graphs/mandel.py | 2 +- gallery/misc/julia.py | 2 +- manual/color.tex | 19 +++---- manual/{palettename.py => gradientname.py} | 10 ++-- manual/gradientname.tex | 3 ++ manual/graph.tex | 6 +-- manual/palettename.tex | 3 -- pyx/color.py | 86 +++++++++++++++--------------- pyx/graph/style.py | 8 +-- test/functional/test_bargraph.py | 2 +- test/functional/test_graph.py | 6 +-- 15 files changed, 86 insertions(+), 84 deletions(-) rename manual/{palettename.py => gradientname.py} (82%) create mode 100644 manual/gradientname.tex delete mode 100644 manual/palettename.tex diff --git a/CHANGES b/CHANGES index f366c607..6c933e40 100644 --- a/CHANGES +++ b/CHANGES @@ -32,13 +32,12 @@ TODO: - add styles using curves instead of lines - canvas module: - contructor should only take a texrunner keyword argument - - set method??? - SVG support - stroking of patterns does not work in PDF - style and color module: - support modification of existing styles via __call__ - bbox module: - - height -> getheight, ... + - rewrite height, etc. using properties - dvifile module: - support single-character mode - deformer module: @@ -79,6 +78,10 @@ TODO: - describe creation and modification (inplace and ``modify by new'') of graph data +0.10 (200X/XX/XX): + - color module: + - renamed: palette->gradient, functionpalette->functiongradient, linearpalette->lineargradient + - new class palette representing a discrete ordered list of colors 0.9 (2006/05/24): - most important changes (to be included in the release notes): diff --git a/examples/graphs/change.py b/examples/graphs/change.py index b2b4b20d..85ab9074 100644 --- a/examples/graphs/change.py +++ b/examples/graphs/change.py @@ -9,6 +9,6 @@ g.plot([graph.data.function("x(y)=y**4", title=r"$x = y^4$"), graph.data.function("x(y)=y", title=r"$x = y$"), graph.data.function("y(x)=x**2", title=r"$y = x^2$"), graph.data.function("y(x)=x**4", title=r"$y = x^4$")], - [graph.style.line([color.palette.Rainbow])]) + [graph.style.line([color.gradient.Rainbow])]) g.writeEPSfile("change") g.writePDFfile("change") diff --git a/examples/graphs/change.txt b/examples/graphs/change.txt index aa39face..ee5b0540 100644 --- a/examples/graphs/change.txt +++ b/examples/graphs/change.txt @@ -8,9 +8,9 @@ In order to display more than one data set, we pass a list of data sets to the three lists of `graph.data.function` instances. For each data set we also set a title using the corresponding keyword argument of the data class. -For a more colorful output, we pass the `color.palette.Rainbow` color palette +For a more colorful output, we pass the `color.gradient.Rainbow` color gradient to the `graph.style.line` class. PyX then automatically chooses color spanning -the whole range of the rainbow palette. +the whole range of the rainbow gradient. ! If you look at the output, you will notice that not only the colors are cycled through, but also the line style changes. The reason for this behavior @@ -20,10 +20,10 @@ additional line attributes, these are appended to the default attributes (this is generally the case in PyX). Consequently, you get a change of both the color and the line style. If you only want to change the color, either pass the desired line style explicitly, i.e., use - graph.style.line([style.linestyle.solid, color.palette.Rainbow]) + graph.style.line([style.linestyle.solid, color.gradient.Rainbow]) or clear a previous setting of the line style using the `clear` attribute of the corresponding class: - graph.style.line([style.linestyle.clear, color.palette.Rainbow]) + graph.style.line([style.linestyle.clear, color.gradient.Rainbow]) !! It is also possible to call the `plot` method several times. Note that the changing of the styles is also performed when the style instances are used on diff --git a/examples/graphstyles/changesymbol.py b/examples/graphstyles/changesymbol.py index 8af45140..fb48e852 100644 --- a/examples/graphstyles/changesymbol.py +++ b/examples/graphstyles/changesymbol.py @@ -5,14 +5,14 @@ from pyx import * class changesymbol(graph.style.symbol): def __init__(self, sizecolumnname="size", colorcolumnname="color", - palette=color.palette.Rainbow, + gradient=color.gradient.Rainbow, symbol=graph.style.symbol.circle, symbolattrs=[deco.filled, deco.stroked([color.gray.black])], **kwargs): # add some configuration parameters and modify some other self.sizecolumnname = sizecolumnname self.colorcolumnname = colorcolumnname - self.palette = palette + self.gradient = gradient graph.style.symbol.__init__(self, symbol=symbol, symbolattrs=symbolattrs, **kwargs) def columnnames(self, privatedata, sharedata, agraph, columnnames): @@ -29,7 +29,7 @@ class changesymbol(graph.style.symbol): # replace the original drawpoint method by a slightly revised one if sharedata.vposvalid and privatedata.symbolattrs is not None: x_pt, y_pt = graph.vpos_pt(*sharedata.vpos) - color = self.palette.getcolor(point[self.colorcolumnname]) + color = self.gradient.getcolor(point[self.colorcolumnname]) privatedata.symbol(privatedata.symbolcanvas, x_pt, y_pt, privatedata.size_pt*point[self.sizecolumnname], privatedata.symbolattrs + [color]) diff --git a/gallery/graphs/mandel.py b/gallery/graphs/mandel.py index 1f0e888d..9a8a6751 100644 --- a/gallery/graphs/mandel.py +++ b/gallery/graphs/mandel.py @@ -36,7 +36,7 @@ g = graph.graphxy(height=8, width=8, x=graph.axis.linear(min=re_min, max=re_max, title=r'$\Re(c)$'), y=graph.axis.linear(min=im_min, max=im_max, title=r'$\Im(c)$')) g.plot(graph.data.list(d, xmin=1, xmax=2, ymin=3, ymax=4, color=5), - [graph.style.rect(color.palette.Rainbow)]) + [graph.style.rect(color.gradient.Rainbow)]) g.dodata() # plot data first, then axes g.writeEPSfile('mandel') g.writePDFfile('mandel') diff --git a/gallery/misc/julia.py b/gallery/misc/julia.py index fadea179..e61d22b3 100644 --- a/gallery/misc/julia.py +++ b/gallery/misc/julia.py @@ -10,7 +10,7 @@ Max_Im = 1.5 Min_Re = -1.5 Max_Re = 1.5 c = 0.41 + 0.3j -p = color.palette.RedBlue +p = color.gradient.RedBlue def rgbcolortostring(c): return "".join([chr(int(255*c.color[name])) for name in "rgb"]) diff --git a/manual/color.tex b/manual/color.tex index ced718e5..8c3c70b8 100644 --- a/manual/color.tex +++ b/manual/color.tex @@ -37,14 +37,15 @@ The file \verb|color.eps| is created and looks like: \includegraphics{color} \end{quote} -\section{Color palettes} +\section{Color gradients} -The color module provides a class \verb|palette| for transitions between -colors. A list of named palettes is available in appendix~\ref{palettename}. +The color module provides a class \verb|gradient| for continous transitions between +colors. A list of named gradients is available in appendix~\ref{gradientname}. -\begin{classdesc}{palette}{min=0, max=1} - This class provides the methods for the \verb|palette|. Different - initializations can be found in \verb|linearpalette| and \verb|functionpalette|. +\begin{classdesc}{gradient}{min=0, max=1} + This class provides the methods for the \verb|gradient|. Different + initializations can be found in \verb|lineargradient| and + \verb|functiongradient|. \var{min} and \var{max} provide the valid range of the arguments for \verb|getcolor|. @@ -56,13 +57,13 @@ colors. A list of named palettes is available in appendix~\ref{palettename}. \begin{funcdesc}{select}{index, n\_indices} When a total number of \var{n\_indices} different colors is needed from the - palette, this method returns the \var{index}-th color. + gradient, this method returns the \var{index}-th color. \end{funcdesc} \end{classdesc} -\begin{classdesc}{linearpalette}{startcolor, endcolor, min=0, max=1} +\begin{classdesc}{lineargradient}{startcolor, endcolor, min=0, max=1} This class provides a linear transition between two given colors. The linear interpolation is performed on the color components of the specific color model. @@ -70,7 +71,7 @@ colors. A list of named palettes is available in appendix~\ref{palettename}. \var{startcolor} and \var{endcolor} must be colors of the same color model. \end{classdesc} -\begin{classdesc}{functionpalette}{functions, type, min=0, max=1} +\begin{classdesc}{functiongradient}{functions, type, min=0, max=1} This class provides an arbitray transition between colors of the same color model. diff --git a/manual/palettename.py b/manual/gradientname.py similarity index 82% rename from manual/palettename.py rename to manual/gradientname.py index cd164751..8a188d6f 100755 --- a/manual/palettename.py +++ b/manual/gradientname.py @@ -16,12 +16,12 @@ pf = graph.data.paramfunction("k", 0, 1, "color, xmin, xmax, ymin, ymax= k, k, 1 y = 0 dy = -0.65 -# we could use palette.__dict__ to get the instances, but we +# we could use gradient.__dict__ to get the instances, but we # would loose the ordering ... instead we just parse the file: # see comment in colorname.py -p = re.compile("(?Ppalette\\.(?P[a-z]+)) += [a-z]+palette\\(.*\\)\n", re.IGNORECASE) +p = re.compile("(?Pgradient\\.(?P[a-z]+)) += [a-z]+gradient\\(.*\\)\n", re.IGNORECASE) lines = imp.find_module("color", pyx.__path__)[0].readlines() firstgraph = None for line in lines: # we yet don't use a file iterator @@ -37,7 +37,7 @@ for line in lines: # we yet don't use a file iterator firstgraph = g = graph.graphxy(ypos=y, width=10, height=0.5, x2=xaxis, y=graph.axis.lin(parter=None)) else: g = graph.graphxy(ypos=y, width=10, height=0.5, x2=graph.axis.linkedaxis(firstgraph.axes["x2"]), y=graph.axis.lin(parter=None)) - g.plot(pf, [graph.style.rect(getattr(pyx.color.palette, m.group("name")))]) + g.plot(pf, [graph.style.rect(getattr(pyx.color.gradient, m.group("name")))]) g.dodata() g.finish() c.insert(g) @@ -45,5 +45,5 @@ for line in lines: # we yet don't use a file iterator y += dy -c.writeEPSfile("palettename") -c.writePDFfile("palettename") +c.writeEPSfile("gradientname") +c.writePDFfile("gradientname") diff --git a/manual/gradientname.tex b/manual/gradientname.tex new file mode 100644 index 00000000..134cf0c2 --- /dev/null +++ b/manual/gradientname.tex @@ -0,0 +1,3 @@ +\chapter{Named gradients} +\label{gradientname} +\centerline{\includegraphics{gradientname}} diff --git a/manual/graph.tex b/manual/graph.tex index ca346e61..54c4ec9d 100644 --- a/manual/graph.tex +++ b/manual/graph.tex @@ -777,12 +777,12 @@ definition is: order to prevent numerical instabilities. \end{classdesc} % }}} -\begin{classdesc}{rect}{palette=color.palette.Grey} % {{{ +\begin{classdesc}{rect}{gradient=color.gradient.Grey} % {{{ This class is a style to plot colored rectangles into a two-dimensional graph. The size of the rectangles is taken from the data provided by the \class{range} style. The additional data column named \code{color} specifies the color of the rectangle - defined by \var{palette}. The valid color range is [0:1]. + defined by \var{gradient}. The valid color range is [0:1]. \begin{note} Although this style can be used for plotting colored surfaces, it @@ -854,7 +854,7 @@ definition is: \begin{classdesc}{bar}{barattrs=[]} % {{{ This class draws bars in a bar graph. The bars are filled using \var{barattrs}. \var{barattrs} is merged with \code{defaultbarattrs} - which is a list containing \code{[color.palette.Rainbow, + which is a list containing \code{[color.gradient.Rainbow, deco.stroked([color.grey.black])]}. \end{classdesc} % }}} % }}} diff --git a/manual/palettename.tex b/manual/palettename.tex deleted file mode 100644 index 34713ec8..00000000 --- a/manual/palettename.tex +++ /dev/null @@ -1,3 +0,0 @@ -\chapter{Named palettes} -\label{palettename} -\centerline{\includegraphics{palettename}} diff --git a/pyx/color.py b/pyx/color.py index 21dc9509..e3f0a43e 100644 --- a/pyx/color.py +++ b/pyx/color.py @@ -316,16 +316,20 @@ cmyk.White = cmyk(0, 0, 0, 0) cmyk.white = cmyk.White cmyk.black = cmyk.Black +class palette(attr.changelist): + """color palettes -class palette(color, attr.changeattr): + A color palette is a discrete, ordered list of colors""" - """base class for all palettes +palette.clear = attr.clearclass(palette) - A palette is a collection of colors with a single parameter ranging from 0 to 1 - to address them""" - def __init__(self): - color.__init__(self) +class gradient(attr.changeattr): + + """base class for color gradients + + A gradient is a continuous collection of colors with a single parameter ranging from 0 to 1 + to address them""" def getcolor(self, param): """return color corresponding to param""" @@ -339,19 +343,14 @@ class palette(color, attr.changeattr): param = index / (n_indices - 1.0) return self.getcolor(param) - def processPS(self, file, writer, context, registry, bbox): - self.getcolor(0).processPS(file, writer, context) - - def processPDF(self, file, writer, context, registry, bbox): - self.getcolor(0).processPDF(file, writer, context) +gradient.clear = attr.clearclass(gradient) -class linearpalette(palette): +class lineargradient(gradient): - """linearpalette is a collection of two colors for a linear transition between them""" + """collection of two colors for a linear transition between them""" def __init__(self, mincolor, maxcolor): - palette.__init__(self) if mincolor.__class__ != maxcolor.__class__: raise ValueError self.colorclass = mincolor.__class__ @@ -365,9 +364,9 @@ class linearpalette(palette): return self.colorclass(**colordict) -class functionpalette(palette): +class functiongradient(gradient): - """functionpalette is a collection of colors for an arbitray non-linear transition between them + """collection of colors for an arbitray non-linear transition between them parameters: functions: a dictionary for the color values @@ -375,7 +374,6 @@ class functionpalette(palette): """ def __init__(self, functions, type): - palette.__init__(self) if type == "cmyk": self.colorclass = cmyk elif type == "rgb": @@ -395,37 +393,37 @@ class functionpalette(palette): return self.colorclass(**colordict) -palette.Gray = linearpalette(gray.white, gray.black) -palette.Grey = palette.Gray -palette.ReverseGray = linearpalette(gray.black, gray.white) -palette.ReverseGrey = palette.ReverseGray -palette.BlackYellow = functionpalette(functions={#(compare this with reversegray above) +gradient.Gray = lineargradient(gray.white, gray.black) +gradient.Grey = gradient.Gray +gradient.ReverseGray = lineargradient(gray.black, gray.white) +gradient.ReverseGrey = gradient.ReverseGray +gradient.BlackYellow = functiongradient(functions={ # compare this with reversegray above "r":(lambda x: 2*x*(1-x)**5 + 3.5*x**2*(1-x)**3 + 2.1*x*x*(1-x)**2 + 3.0*x**3*(1-x)**2 + x**0.5*(1-(1-x)**2)), "g":(lambda x: 1.5*x**2*(1-x)**3 - 0.8*x**3*(1-x)**2 + 2.0*x**4*(1-x) + x**4), "b":(lambda x: 5*x*(1-x)**5 - 0.5*x**2*(1-x)**3 + 0.3*x*x*(1-x)**2 + 5*x**3*(1-x)**2 + 0.5*x**6)}, type="rgb") -palette.RedGreen = linearpalette(rgb.red, rgb.green) -palette.RedBlue = linearpalette(rgb.red, rgb.blue) -palette.GreenRed = linearpalette(rgb.green, rgb.red) -palette.GreenBlue = linearpalette(rgb.green, rgb.blue) -palette.BlueRed = linearpalette(rgb.blue, rgb.red) -palette.BlueGreen = linearpalette(rgb.blue, rgb.green) -palette.RedBlack = linearpalette(rgb.red, rgb.black) -palette.BlackRed = linearpalette(rgb.black, rgb.red) -palette.RedWhite = linearpalette(rgb.red, rgb.white) -palette.WhiteRed = linearpalette(rgb.white, rgb.red) -palette.GreenBlack = linearpalette(rgb.green, rgb.black) -palette.BlackGreen = linearpalette(rgb.black, rgb.green) -palette.GreenWhite = linearpalette(rgb.green, rgb.white) -palette.WhiteGreen = linearpalette(rgb.white, rgb.green) -palette.BlueBlack = linearpalette(rgb.blue, rgb.black) -palette.BlackBlue = linearpalette(rgb.black, rgb.blue) -palette.BlueWhite = linearpalette(rgb.blue, rgb.white) -palette.WhiteBlue = linearpalette(rgb.white, rgb.blue) -palette.Rainbow = linearpalette(hsb(0, 1, 1), hsb(2.0/3.0, 1, 1)) -palette.ReverseRainbow = linearpalette(hsb(2.0/3.0, 1, 1), hsb(0, 1, 1)) -palette.Hue = linearpalette(hsb(0, 1, 1), hsb(1, 1, 1)) -palette.ReverseHue = linearpalette(hsb(1, 1, 1), hsb(0, 1, 1)) +gradient.RedGreen = lineargradient(rgb.red, rgb.green) +gradient.RedBlue = lineargradient(rgb.red, rgb.blue) +gradient.GreenRed = lineargradient(rgb.green, rgb.red) +gradient.GreenBlue = lineargradient(rgb.green, rgb.blue) +gradient.BlueRed = lineargradient(rgb.blue, rgb.red) +gradient.BlueGreen = lineargradient(rgb.blue, rgb.green) +gradient.RedBlack = lineargradient(rgb.red, rgb.black) +gradient.BlackRed = lineargradient(rgb.black, rgb.red) +gradient.RedWhite = lineargradient(rgb.red, rgb.white) +gradient.WhiteRed = lineargradient(rgb.white, rgb.red) +gradient.GreenBlack = lineargradient(rgb.green, rgb.black) +gradient.BlackGreen = lineargradient(rgb.black, rgb.green) +gradient.GreenWhite = lineargradient(rgb.green, rgb.white) +gradient.WhiteGreen = lineargradient(rgb.white, rgb.green) +gradient.BlueBlack = lineargradient(rgb.blue, rgb.black) +gradient.BlackBlue = lineargradient(rgb.black, rgb.blue) +gradient.BlueWhite = lineargradient(rgb.blue, rgb.white) +gradient.WhiteBlue = lineargradient(rgb.white, rgb.blue) +gradient.Rainbow = lineargradient(hsb(0, 1, 1), hsb(2.0/3.0, 1, 1)) +gradient.ReverseRainbow = lineargradient(hsb(2.0/3.0, 1, 1), hsb(0, 1, 1)) +gradient.Hue = lineargradient(hsb(0, 1, 1), hsb(1, 1, 1)) +gradient.ReverseHue = lineargradient(hsb(1, 1, 1), hsb(0, 1, 1)) class PDFextgstate(pdfwriter.PDFobject): diff --git a/pyx/graph/style.py b/pyx/graph/style.py index a8600b1a..1a38de19 100644 --- a/pyx/graph/style.py +++ b/pyx/graph/style.py @@ -809,8 +809,8 @@ class rect(_style): needsdata = ["vrange", "vrangeminmissing", "vrangemaxmissing"] - def __init__(self, palette=color.palette.Grey): - self.palette = palette + def __init__(self, gradient=color.gradient.Grey): + self.gradient = gradient def columnnames(self, privatedata, sharedata, graph, columnnames): if len(graph.axesnames) != 2: @@ -846,7 +846,7 @@ class rect(_style): p.append(graph.vgeodesic_el(xvmax, yvmax, xvmin, yvmax)) p.append(graph.vgeodesic_el(xvmin, yvmax, xvmin, yvmin)) p.append(path.closepath()) - privatedata.rectcanvas.fill(p, [self.palette.getcolor(point["color"])]) + privatedata.rectcanvas.fill(p, [self.gradient.getcolor(point["color"])]) def key_pt(self, privatedata, sharedata, graph, x_pt, y_pt, width_pt, height_pt): raise RuntimeError("Style currently doesn't provide a graph key") @@ -1349,7 +1349,7 @@ class bar(_style): needsdata = ["vbarrange"] - defaultbarattrs = [color.palette.Rainbow, deco.stroked([color.grey.black])] + defaultbarattrs = [color.gradient.Rainbow, deco.stroked([color.grey.black])] def __init__(self, barattrs=[]): self.barattrs = barattrs diff --git a/test/functional/test_bargraph.py b/test/functional/test_bargraph.py index 31f1658e..44c56a65 100755 --- a/test/functional/test_bargraph.py +++ b/test/functional/test_bargraph.py @@ -33,7 +33,7 @@ def test_bar4(c, x, y): graph.data.data(graph.data.list([['x', 4, 9], ['y', 5, 8], ['z', 6, 7]], id=1, y=2, ystack1=3, title="test"), xname="id, ('B', 'X')"), graph.data.data(graph.data.list([['x', 7, 6], ['y', 8, 5], ['z', 9, 4]], id=1, y=2, ystack1=3, title="test"), xname="id, ('B', 'Y')"), graph.data.data(graph.data.list([['x', 10, 3], ['y', 11, 2], ['z', 12, 1]], id=1, y=2, ystack1=3, title="test"), xname="id, ('B', 'Z')")], - [graph.style.barpos(fromvalue=0), graph.style.bar(), graph.style.stackedbarpos("ystack1", addontop=1), graph.style.bar([color.palette.ReverseRainbow])]) + [graph.style.barpos(fromvalue=0), graph.style.bar(), graph.style.stackedbarpos("ystack1", addontop=1), graph.style.bar([color.gradient.ReverseRainbow])]) c = canvas.canvas() test_bar(c, 0, 0) diff --git a/test/functional/test_graph.py b/test/functional/test_graph.py index e5ccf47d..bcb32a4e 100755 --- a/test/functional/test_graph.py +++ b/test/functional/test_graph.py @@ -13,14 +13,14 @@ def test_multiaxes_data(c, x, y): painter=graph.axis.painter.regular(titledirection=None)), y2=graph.axis.log(title="$P_2$"), y3=graph.axis.log(title="$PPP_3$", - painter=graph.axis.painter.regular(titledirection=graph.axis.painter.rotatetext(45), gridattrs=[color.palette.RedGreen]), + painter=graph.axis.painter.regular(titledirection=graph.axis.painter.rotatetext(45), gridattrs=[color.gradient.RedGreen]), texter=graph.axis.texter.decimal(equalprecision=1)), y5=graph.axis.log(title="$P_5$"))) g.plot((graph.data.file("data/testdata", x=1, y="sqrt(sqrt($3))", title="mytitle"), graph.data.file("data/testdata", x=1, y2=4), graph.data.file("data/testdata", x=1, y3=5, title=None), graph.data.file("data/testdata", x=1, y5=6)), - styles=[graph.style.symbol(symbolattrs=[deco.stroked.clear, color.palette.RedGreen, graph.style.symbol.changestrokedfilled], symbol=graph.style.symbol.changesquaretwice)]) + styles=[graph.style.symbol(symbolattrs=[deco.stroked.clear, color.gradient.RedGreen, graph.style.symbol.changestrokedfilled], symbol=graph.style.symbol.changesquaretwice)]) g.finish() def test_piaxis_function(c, x, y): @@ -28,7 +28,7 @@ def test_piaxis_function(c, x, y): g = c.insert(graph.graphxy(x, y, height=5, x=xaxis)) #g = c.insert(graph.graphxy(x, y, height=5, x=xaxis, x2=xaxis)) g.plot([graph.data.function("y(x)=sin(x-i*pi/10)", context={"i": i}) for i in range(20)], - styles=[graph.style.line(lineattrs=[color.palette.Hue])]) + styles=[graph.style.line(lineattrs=[color.gradient.Hue])]) g.finish() def test_textaxis_errorbars(c, x, y): -- 2.11.4.GIT