Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
321 views
in Technique[技术] by (71.8m points)

python 3.x - How does parameters 'c' and 'cmap' behave in a matplotlib scatter plot?

For the pyplot.scatter(x,y,s,c....) function ,

The matplotlib docs states that :

c : color, sequence, or sequence of color, optional, default: 'b' The marker color. Possible values:

A single color format string. A sequence of color specifications of length n. A sequence of n numbers to be mapped to colors using cmap and norm. A 2-D array in which the rows are RGB or RGBA. Note that c should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped. If you want to specify the same RGB or RGBA value for all points, use a 2-D array with a single row.

However i do not understand how i can change the colors of the datapoints as i wish .

I have this piece of code :

import matplotlib.pyplot as plt
import numpy as np
import sklearn
import sklearn.datasets
import sklearn.linear_model
import matplotlib


%matplotlib inline
matplotlib.rcParams['figure.figsize'] = (13.0, 9.0)

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.55)
print(y)
plt.scatter(X[:,0], X[:,1], c=y)#, cmap=plt.cm.Spectral)

the output plot

How can i change the colours to suppose black and green datapoints if i wish ? or something else ? Also please explain what exactly cmap does .

Why my plots are magenta and blue every time i use plt.cm.Spectral ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are essentially two option on how to colorize scatter points.

1. External mapping

You may externally map values to color and supply a list/array of those colors to the scatter's c argument.

z = np.array([1,0,1,0,1])
colors = np.array(["black", "green"])
plt.scatter(x,y, c=colors[z])

2. Internal mapping

Apart from explicit colors, one can also supply a list/array of values which should be mapped to colors according to a normalization and a colormap.

  • A colormap is a callable that takes float values between 0. and 1. as input and returns a RGB color.
  • A normalization is a callable that takes any number as input and outputs another number, based on some previously set limits. The usual case of Normalize would provide a linear mapping of values between vmin and vmax to the range between 0. and 1..

The natural way to obtain a color from some data is hence to chain the two,

cmap = plt.cm.Spectral
norm = plt.Normalize(vmin=4, vmax=5)
z = np.array([4,4,5,4,5])
plt.scatter(x,y, c = cmap(norm(z)))

Here the value of 4 would be mapped to 0 by the normalzation, and the value of 5 be mapped to 1, such that the colormap provides the two outmost colors.

This process happens internally in scatter if an array of numeric values is provided to c.

A scatter creates a PathCollection, which subclasses ScalarMappable. A ScalarMappable consists of a colormap, a normalization and an array of values. Hence the above is internalized via

plt.scatter(x,y, c=z, norm=norm, cmap=cmap)

If the minimum and maximum data are to be used as limits for the normalization, you may leave that argument out.

plt.scatter(x,y, c=z, cmap=cmap)

This is the reason that the output in the question will always be purple and yellow dots, independent of the values provided to c.

Coming back to the requirement of mapping an array of 0 and 1 to black and green color you may now look at the colormaps provided by matplotlib and look for a colormap which comprises black and green. E.g. the nipy_spectral colormap

enter image description here

Here black is at the start of the colormap and green somewhere in the middle, say at 0.5. One would hence need to set vmin to 0, and vmax, such that vmax*0.5 = 1 (with 1 the value to be mapped to green), i.e. vmax = 1./0.5 == 2.

import matplotlib.pyplot as plt
import numpy as np
x,y = np.random.rand(2,6)
z = np.array([0,0,1,1,0,1])

plt.scatter(x,y, c = z, 
            norm = plt.Normalize(vmin=0, vmax=2),
            cmap = "nipy_spectral")

plt.show()

enter image description here

Since there may not always be a colormap with the desired colors available and since it may not be straight forward to obtain the color positions from existing colormaps, an alternative is to create a new colormaps specifically for the desired purpose.

Here we might simply create a colormap of two colors black and green.

matplotlib.colors.ListedColormap(["black", "green"])

We would not need any normalization here, because we only have two values and can hence rely on automatic normalization.

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
x,y = np.random.rand(2,6)
z = np.array([0,0,1,1,0,1])

plt.scatter(x,y, c = z, cmap = mcolors.ListedColormap(["black", "green"]))

plt.show()

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...