Charanjit Pabla
Charanjit Pabla

Reputation: 407

Scatter Plot with Colobar

I am trying to plot some more complex data but for the sake of example, I have simplified to show what I am trying to do but is not working. See the below code and output image. Notice I have a section commented out. I essentially want to plot the commented section on top but I get an error:

ValueError: to_rgba: Invalid rgba arg "0.0" to_rgb: Invalid rgb arg "0.0" cannot convert argument to rgb sequence

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

x1=[1.0,1.5,2.2,1.8]
y1=[1.1,1.4,2.0,1.75]

x2=[1.5,2.5,3.0,3.5,3.6]
y2=[1.3,2.2,3.3,3.4,3.5]

height=[0.0,1.0,2.0,3.0,4.0]

fig = plt.figure(figsize=(8, 8))
ax=plt.subplot()
divider=make_axes_locatable(ax)
sc=plt.scatter(x2, y2, c=height, vmin=np.min(height)-0.5,
           vmax=np.max(height)+0.5, marker='o', s=40, 
           cmap=plt.cm.get_cmap('jet', len(height)))

#sc=plt.scatter(x1, y1, c=height, vmin=np.min(height)-0.5,
#               vmax=np.max(height)+0.5, marker='o', s=40, 
#               cmap=plt.cm.get_cmap('jet', len(height)))

cax=divider.append_axes("right", size='5%', pad=0.05)
cbar=plt.colorbar(sc, cax=cax, ticks=np.arange(np.min(height),np.max(height)+1,1.0))

I do have some sort of an idea of the error. Because the second set of data does not share the same length as the first or vise versa, the color coding gets confused. Is there a way to do something like this?

A simple plot from above code

Upvotes: 0

Views: 232

Answers (1)

Dux
Dux

Reputation: 1246

The c argument of scatter expects either a single color specifier (e.g. 'blue') or a series of color specifiers (e.g. ['blue', 'red', ...]) or a series of numbers that are mapped using the colormap (e.g. [1, 2, 3, 4, ...], as you used it here).

However, in your commented-out case, the series you provide is not matchable to your data, so scatter doesn't know what to do with it. What do you want to do with it?

You might e.g. try

height1 = np.arange(len(x1))
sc=plt.scatter(x1, y1, c=height1, vmin=np.min(height1)-0.5,
               vmax=np.max(height1)+0.5, marker='o', s=40, 
               cmap=plt.cm.get_cmap('jet', len(height)))

Edit: The way this works is as follows: Every data point (x, y) is associated with an element in c, that is c[i] is assigned to the marker at (x[i], y[i]). This is why c, x and y all have to have the same length, otherwise the matching doesn't work. NaN values in c will not help here. However, your values in c are only converted to colors using the colormap you specififed. And the range of the colormap is determined by vmin and vmax. So, to make sure your color use the same data range for all your data sets, just precompute vmin and vmax prior to plotting using all data and set it accordingly.

So in your case:

h1 = np.arange(len(x1))
h2 = np.arange(len(x2))

minval = min([np.min(h) for h in [h1, h2]])
maxval = max([np.max(h) for h in [h1, h2]])
nh = len(np.arange(minval, maxval+1, 1))

and then

sc=plt.scatter(x1, y1, c=h1, marker='o', s=40, 
               vmin=minval-0.5, vmax=maxval+0.5, 
               cmap=plt.cm.get_cmap('jet', nh)
          )

and for the colorbar

cbar=plt.colorbar(sc, cax=cax, ticks=np.arange(minval, maxval+1,1.0))

Upvotes: 2

Related Questions