Ask Your Question

Using colormaps for several curves in a single plot (lists)

asked 2018-11-16 17:54:22 +0200

JC gravatar image

I would like to plot in a simgle fingure several curves, with the colors changing according to a colormap. More precisely, I want to plot some partial sums of a power series, and would like to use the "Blues" colormap to do this. I am using lists to produce the figures / functions. I can actually do something reasonable with color =(?,?,?), but want to be able to use the colormaps. Here is what I got :

Terms = [x^(2+j)*(2+(-1)^(j+1)) for j in range(10)]
Sums = [sum(Terms[0:n]) for n in range(10)]
Figures = [plot(Sums[j], (x,-1.2,1.2), ymin=-3, ymax = 3, color= (0,1-j/10,j/10)) for j in range(10)]
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2018-11-16 19:24:00 +0200

slelievre gravatar image

updated 2018-11-16 21:07:28 +0200

Here is one way to use a colormap with your plots.

In this example, we set the number of curves, and run through the colormap in that many steps.

sage: cm = colormaps.Blues
sage: nmax = 20
sage: color = lambda j: cm(floor(j*255/nmax))[:3]
sage: Terms = [x^(2+j)*(2+(-1)^(j+1)) for j in range(nmax)]
sage: Sums = [sum(Terms[0:n]) for n in range(nmax)]
sage: Figures = [plot(Sums[j], (x, -1.2, 1.2), ymin=-3, ymax=3, color=color(j)) for j in range(nmax)]
sage: f = sum(Figures)

Edit. (To answer follow-up question in the comment.)

Colormaps have 256 levels numbered 0 to 255, so color above maps [0 .. nmax - 1] into [0 .. 255].

To leave out the first half of the colormap, use instead:

sage: color = lambda j: cm(floor(128 + j*127/nmax))[:3]

or if you want to go nonlinearly using some function h from [0 .. nmax-1] to the interval [0, 1], just use

sage: color = lambda j: cm(floor(255*h(j))[:3]

(That looks better indeed.)

The reason for [:3] is that a colormap returns four values, corresponding to R, G, B and opacity (also known as alpha), but typically opacity is 1.0 throughout (since most colormaps do not play with transparency).

To further refine the above and make the transition through colors more continuous, instead of using cm(floor(...)) one could use the fractional part of 255*h(j) to move gradually between the colors at floor(255*h(j)) and ceil(255*h(j)) in the colormap... (Not clear one could perceive the effect of that though!)

To do that, given a function h as above, you could do

def color(j):
    h = RR(255*h(j))
    r0, g0, b0 = cm(h.floor())[:3] # rgb at floor
    r1, g1, b1 = cm(h.ceil())[:3] # rgb at ceiling
    f = h.frac() # fractional part
    r = (1-f) * r0 + f * r1
    g = (1-f) * g0 + f * g1
    b = (1-f) * b0 + f * b1
    return r, g, b
edit flag offensive delete link more


Great, that is exactly what I was looking for. Next tweak : make the color function to beheave non linearly, or for instance start at 0.5 in order to avoid too light curves.

JC gravatar imageJC ( 2018-11-16 19:51:49 +0200 )edit

Edited answer to address this follow-up question.

slelievre gravatar imageslelievre ( 2018-11-18 19:10:50 +0200 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2018-11-16 17:54:22 +0200

Seen: 352 times

Last updated: Nov 16 '18