简体   繁体   中英

Using lists to assign colors to a series in matplotlib?

I thought the easiest way to make a scatterplot with N different series (like in excel) would be to have 3 lists:i) x_coordinates would have N lists containing the X positions; ii) y_coordinates would also have N lists containing the Y positions; and iii) color_map would have N elements containing the different RGB colors per series.

My problem is that the order gets weird on plotting the colors for the markers. Why is this happening and how do I fix it?

import matplotlib.pyplot as plt
import random
x_coordinates = [(range(1,4))]*2
y_coordinates = [[3,4,5],[2,2,2]]
color_map = []
for i in range(0,len(x_coordinates)):
    r = lambda: random.randint(0,255)
    rgb_hex = ('#%02X%02X%02X' % (r(),r(),r()))
    color_map.append(rgb_hex)
plt.scatter(x_coordinates,y_coordinates,c=color_map)
plt.show()

Lists for x/y coordinates and colors

[[1, 2, 3], [1, 2, 3]] #x
[[3, 4, 5], [2, 2, 2]] #y
['#E6764F', '#A12678'] #colors

在此输入图像描述

The colors are specified per point, not per series. The coloring you see is that it uses the first color for the first point of the first series, then the next color for the next point of that series, then cycles back to the first color for the third point of the first series, and so on.

I don't know of any way to specify the colors per series with the data in the format you show. You'll have to make a single sequence with all the colors, you want, eg:

# make first series red and second series blue
color_map = ["#FF0000"]*3 + ["#0000FF"]*3

Alternatively, you could transpose your x and y data so that the series are in columns rather than rows (which I think is how matplotlib interprets them anyway). Then specifying two colors will do what you want.

I think the basic problem is that you have to rethink if you really need the scatter function. From what you posted I think it would be enough to use plot repeatedly. scatter produces a series of colored markers (with the possibility of assigning varying colors and sizes to the markers), whereas plot just plots lines with a single color. However, these lines can also have markers at the points (with a single color). So the way to approach this is to create a line plot per series. (If you don't want the line, you can set the linestyle to 'none' . But wrt your previous question I believe that you want to do that anyways)

NB: I also applied some cosmetics to your code: 1) there is no need to create hex strings for the colors. Simply use lists/tuples with 3 elements scaled from 0 to 1. 2) You can simply save the random function to r. No need to create a lambda function.

import matplotlib.pyplot as plt
import random

# x and y coordinates
x_coordinates = [range(1,4)]*2
y_coordinates = [[3,4,5],[2,2,2]]

# colors (one per series --> 2 in this example)
colors = []
r = random.random
for i in range(0,len(x_coordinates)):
    rgb =  (r(),r(),r())
    colors.append(rgb)

# iterate over the series
for x, y, c in zip(x_coordinates, y_coordinates, colors):
    plt.plot(x, y, color=c, linestyle='-', marker='o', markeredgecolor='k',
            markersize=10)

# show the figure
plt.margins(x=0.1, y=0.1)
plt.show()

Result: 在此输入图像描述

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