majpark
majpark

Reputation: 103

Matplotlib: common color map for 2 scatter plots within the same plot

I have bi-variate time-series stored in 2D Numpy arrays. I would like to plot both channels of the series on the same plot. Each series should be represented by a line which is colored according to the channel. On top of these lines, I want to plot the points of the series as dots. These should be colored according to values in a second 2D Numpy array of the same shape. My question is: how to set a color-map for the dots in a range that is common to both channels?

I managed to get lines of different colors and dots for each series with a double call of plt.plot() and plt.scatter() with something like:

import matplotlib.pyplot as plt
import numpy as np

# Bivariate time-series of length 10
nchannel, length = 2, 10
array_series = np.random.random((nchannel, length))
array_colors = np.vstack([np.repeat(0, length), np.repeat(1, length)])

colormap = 'jet'
plt.plot(np.arange(length), array_series[0,:])
plt.scatter(np.arange(length), array_series[0,:], c=array_colors[0,:], cmap=colormap)
plt.plot(np.arange(length), array_series[1,:])
plt.scatter(np.arange(length), array_series[1,:], c=array_colors[1,:], cmap=colormap)

This produces: Current output

This is not the desired output because all dots are dark blue, so the distinction between 0 and 1 in array_colors is lost. I looked for something like replacing plt.scatter(..., c=array_colors[i,:], cmap=colormap) by plt.scatter(..., c=array_colors, cmap=colormap). The latter, however, raises an error. Any idea to solve this would be welcome!

Upvotes: 1

Views: 1779

Answers (2)

rtoijala
rtoijala

Reputation: 1209

You can use the parameters vmin and vmax.

Pass as vmin the global minimum value, and as vmax the global maximum value. This will cause all calls to scatter to scale the values in the same range, producing a unified color scale.

Example:

import matplotlib.pyplot as plt
import numpy as np

nchannel, length = 2, 10
array_series = np.random.random((nchannel, length))
array_colors = np.vstack([np.repeat(0, length), np.repeat(1, length)])

colormap = 'jet'
vmin = np.min(array_colors)
vmax = np.max(array_colors)
x = np.arange(length)

plt.plot(x, array_series[0,:])
plt.scatter(x, array_series[0,:], vmin=vmin, vmax=vmax, c=array_colors[0,:], cmap=colormap)
plt.plot(x, array_series[1,:])
plt.scatter(x, array_series[1,:], vmin=vmin, vmax=vmax, c=array_colors[1,:], cmap=colormap)

Upvotes: 1

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339765

I guess you can just use the flat version of the array:

import matplotlib.pyplot as plt
import numpy as np

# Bivariate time-series of length 10
nchannel, length = 2, 10
array_series = np.random.random((nchannel, length))
array_colors = np.random.random((nchannel, length))

x = np.arange(length)

plt.plot(x, array_series[0,:])
plt.plot(x, array_series[1,:])

xs = np.tile(x, nchannel)
plt.scatter(xs, array_series.flat, c=array_colors.flat)

plt.show()

Upvotes: 1

Related Questions