Beane
Beane

Reputation: 586

Issue with Matplotlib scatterplot and Color maps

I am working on a project that involves applying colormaps to scatterplots generated in matplotlib. My code works as expected, unless the scatterplot being generated has exactly four points. This is illustrated in the following code:

import numpy as np
import matplotlib.pyplot as plt

cmap = plt.get_cmap('rainbow_r')

z = np.arange(20)
plt.close()
plt.figure(figsize=[8,6])

for i in range(1,11):
    x = np.arange(i)
    y = np.zeros(i) + i
    plt.scatter(x, y, c=cmap(i / 10), edgecolor='k', label=i, s=200)

plt.legend()
plt.show()

This code generates the following plot:

matplotlib plot

Each row should consist of points of the same color, but that is not the case for the row with four points.

I assume it has to do with the fact that the color selected from the colormap is returned as a tuple of 4 floats, as illustrated below:

print(cmap(0.4))
>>  (0.69999999999999996, 0.95105651629515364, 0.58778525229247314, 1.0)

Assuming that this is the source of the issue, I have no idea how to fix it.

Upvotes: 5

Views: 1546

Answers (2)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339660

This is a common pitfall, such that the documentation espectially mentions it:

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.

It also directly gives you the solution:

c can be a 2-D array in which the rows are RGB or RGBA, however, including the case of a single row to specify the same color for all points.

In this case:

c=np.atleast_2d(cmap(i/10.))


A different option is of course to specify the color as a string such that this abiguity is resolved.

c = matplotlib.colors.rgb2hex(cmap(i/10.))

Upvotes: 4

Jeremy
Jeremy

Reputation: 86

I played around a little with your code and basically you were on to the problem; the similar dimensions of the cmap values with the data caused them to be interpreted differently for the "4" case.

This seems to work correctly:

plt.scatter(x, y, c=[cmap(i / 10)], edgecolor='k', label=i, s=200)

(List constructor around return value from cmap)

fixed_chart

Upvotes: 4

Related Questions