简体   繁体   中英

How to create multiple matplotlib plots while using colormap as a legend?

I have a set of data like this (x1, y1, z1), (x2, y2, z2) where x$ and y$ are arrays while z$ is a floating point number

I want to plot something like in just one window while ordering the plots based on z$. Ideally I would like to show the different plots with a changing gradient of color based on z$.

plt.plot(x1, y1) #color of line based on z1
plt.plot(x2, y2) #color of line based on z2
plt.plot(x3, y3) #color of line based on z3
plt.plot(x4, y4) #color of line based on z4
plt.plot(x5, y5) #color of line based on z5

I have added this graph as an example of what I want to do在此处输入图片说明

This turned out to be a bit tricky, in particular getting the gradient. See this SO question (and answers). I borrowed the rainbow function(with modification for matplotlib) from it: Paint me a Rainbow

#include numpy as np
#include math

def rainbow():
    """use as a generator, have to divide each output by 255 for color in matplotlib"""
    r, g, b = 255, 0, 0
    for g in range(256):
        yield r/255, g/255, b/255,
    for r in range(255, -1, -1):
        yield r/255, g/255, b/255,
    for b in range(256):
        yield r/255, g/255, b/255,
    for g in range(255, -1, -1):
        yield r/255, g/255, b/255,
    for r in range(256):
        yield r/255, g/255, b/255,
    for b in range(255, -1, -1):
        yield r/255, g/255, b/255,

def map_colors(data):
    """Data must be in form ((x1, y1, z1), (x2,y2,z2), ...) with z being the 
    color index identifier, x1 and y1 arrays for 2D line, tuples should be 
    sorted by z-value"""
    zvals = []
    for mytuple in data:
        zvals.append(mytuple[2])
    #note this range (10,1500) covers the (mostly) full rainbow (no violet) but a 
    #tighter gradient can be obtained with, for example (400, 800, len(zvals))
    color_index = [math.floor(x) for x in np.linspace(10, 1500, len(zvals))]
    foo = list(rainbow())
    return [foo[x] for x in color_index]

That's the main bit; to use this just call it in another function like this:

def colorizer(dataset):
    #sort all the plot tuples by the z-value first
    data = sorted(dataset, key=lambda x: x[2])
    #get the r,g,b color indices in sorted order:
    colorset = map_colors(data)
    # generic setup function for matplotlib
    mykwargs = { 'nrows':1, 'ncols':1, 'figsize':(8,6), 'dpi':144,
                'facecolor':'#66ff66' }
    fig, ax = plt.subplots(**mykwargs)
    for i in range(len(data)):
        ax.plot(data[i][0], data[i][1], color=colorset[i])
    plt.show()

Here's a data generator function:

def make_data(n):
    """demo function for generating n exponential plots"""
    power = 1.5
    xvals = np.linspace(1,2,100)
    result = []
    for x in range(n):
        temp = [i**power for i in xvals]
        result.append((tuple(xvals), tuple(temp), round(power, 2)))
        power += 0.1
    return tuple(result)

So if I run this with:

foo = make_data(25)
colorizer(foo)

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM