Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib, multiple scatter subplots with shared colour bar

Tags:

I am trying to create a collection of scatter subplots and would like them to share the same colour bar.

I have followed the guidance here but it seems only applicable to plotting of images where the object has an autoscale property.

The code I am using is as follows:

import matplotlib.pyplot as plt
import numpy
import random

x = []
y = []

for i in range(100):
    x.append(random.normalvariate(100,10))
    y.append(random.normalvariate(100,10))

#Creates a list of length n 
def getRand(n):
    l = []
    for i in range(n):
        l.append(random.normalvariate(1,10))
    return l

f = plt.figure()    
f, axes = plt.subplots(nrows = 2, ncols = 2, sharex=True, sharey = True)

axes[0][0].scatter(getRand(100),getRand(100), c = getRand(100), marker = "x")
axes[0][0].set_xlabel('Crosses', labelpad = 5)

axes[0][1].scatter(getRand(100),getRand(100), c = getRand(100), marker = 'o')
axes[0][1].set_xlabel('Circles', labelpad = 5)

axes[1][0].scatter(getRand(100),getRand(100), c = getRand(100), marker = '*')
axes[1][0].set_xlabel('Stars')

axes[1][1].scatter(getRand(100),getRand(100), c = getRand(100), marker = 's' )
axes[1][1].set_xlabel('Squares')


#Add separate colourbar axes
cbar_ax = f.add_axes([0.85, 0.15, 0.05, 0.7])

#Autoscale none
f.colorbar(axes[0][0], cax=cbar_ax)


plt.show()

This generates the error:

AttributeError: 'AxesSubplot' object has no attribute 'autoscale_None'

The problem is happening when I send the data to the colour bar here:

f.colorbar(axes[0][0], cax=cbar_ax)

Here is the current output, Obviously I would like the colour of the markers to be on the scale bar to the right (I will worry about placing it correctly later):

enter image description here

Is there a away of achieving this for a group of scatter plots such as this and if so how can I modify my code to achieve it?

like image 770
alkey Avatar asked Jul 07 '17 12:07

alkey


1 Answers

The signature of figure.colorbar is

colorbar(mappable, cax=None, ax=None, use_gridspec=True, **kw)

This means that the first argument must be a ScalarMappable, not an axes.

sc = axes[0][0].scatter(..)
fig.colorbar(sc, cax=cbar_ax)

If you want to use the same colorbar for all scatterplots, you would need to use the same normalization for them all.

norm=plt.Normalize(-22,22)
sc = axes[0][0].scatter(getRand(100),getRand(100), c = getRand(100), norm=norm)
fig.colorbar(sc, cax=cbar_ax)

A complete example:

import matplotlib.pyplot as plt
import numpy as np

def getRand(n):
    return np.random.normal(scale=10, size=n)

f = plt.figure()    
f, axes = plt.subplots(nrows = 2, ncols = 2, sharex=True, sharey = True)
norm=plt.Normalize(-22,22)
sc = axes[0][0].scatter(getRand(100),getRand(100), c = getRand(100), marker = "x", norm=norm)
axes[0][0].set_xlabel('Crosses', labelpad = 5)

axes[0][1].scatter(getRand(100),getRand(100), c = getRand(100), marker = 'o', norm=norm)
axes[0][1].set_xlabel('Circles', labelpad = 5)

axes[1][0].scatter(getRand(100),getRand(100), c = getRand(100), marker = '*', norm=norm)
axes[1][0].set_xlabel('Stars')

axes[1][1].scatter(getRand(100),getRand(100), c = getRand(100), marker = 's', norm=norm )
axes[1][1].set_xlabel('Squares')

cbar_ax = f.add_axes([0.85, 0.15, 0.05, 0.7])

f.colorbar(sc, cax=cbar_ax)

plt.show()

enter image description here

like image 133
ImportanceOfBeingErnest Avatar answered Oct 11 '22 14:10

ImportanceOfBeingErnest