0

I wish to generate a basemap map and then plot a number of scatterplots on this basemap (in jupyter-lab) without having to load a new basemap each time. I followed the instructions in this post however when I add a colormap this solution no longer works, adding a new colorbar each time I plot.

Reproducible example:

Cell 1

import matplotlib.pyplot as plt
import pandas as pd
from mpl_toolkits.basemap import Basemap

Cell 2

# generate sample data
data = pd.DataFrame({'lat':[53.360967, 53.3290910], 'lon':[-6.2298519, -6.311015], 'values':[0.25, 0.8]})

Cell 3

# generate the basemap 
%%capture
fig, ax = plt.subplots(figsize=(20,10))
bmap = Basemap(epsg=3857, llcrnrlon=data['lon'][0], llcrnrlat=data['lat'][0],
          urcrnrlon=data['lon'][1], urcrnrlat=data['lat'][1], ax=ax) 
bmap.arcgisimage(service='ESRI_StreetMap_World_2D', xpixels = 12000, verbose= True)

Cell 4

# overlay some data on the basemap 
x, y = bmap(list(data['lon']), list(data['lat'])) 
plot = bmap.scatter(x, y, s=200, marker='o', c=data['values'], cmap='bwr')
cbar = fig.colorbar(plot)
cbar.set_label("Label", rotation=270, labelpad=-10, fontsize=20, weight='semibold')
fig

The first time I run cell 4 I obtain the plot as expected: See here

However every subsequent time I run the cell adds a new colorbar See here

Is there a solution for this or is there a better approach?

Edit: Ideally I would like to end up with a function for generating the basemap and a second for plotting onto the basemap that I can call multiple times for different data on the same map.

Seraf Fej
  • 209
  • 1
  • 9

1 Answers1

0

Managed to figure this one out in the end. The solution is to generate the colorbar with the basemap and independently of the scatterplot using matplotlib.cm.ScalarMappable.

So Cell 3 should look like this:

%%capture
import matplotlib.cm as cm
fig, ax = plt.subplots(figsize=(20,10))

# generate the colorbar
norm= cm.colors.Normalize(vmin=data['values'].min(), vmax=data['values'].max(), clip=False)
SM = cm.ScalarMappable(norm=norm, cmap='bwr')
SM.set_array([])

# generate the basemap 
bmap = Basemap(epsg=3857, llcrnrlon=data['lon'][0], llcrnrlat=data['lat'][0],
          urcrnrlon=data['lon'][1], urcrnrlat=data['lat'][1], ax=ax) 
bmap.arcgisimage(service='ESRI_StreetMap_World_2D', xpixels = 12000, verbose= True)
cbar = fig.colorbar(SM, ax=ax)
cbar.set_label("Label", rotation=270, labelpad=-10, fontsize=20, weight='semibold')

And then Cell 4 can now be run multiple times as follows

x, y = bmap(list(data['lon']), list(data['lat'])) 
plot = bmap.scatter(x, y, s=200, marker='o', c=data['values'], cmap='bwr')
fig
Seraf Fej
  • 209
  • 1
  • 9