问题
I have a shapefile and a series like this:
UF
Acre 261
Alagoas 657
Amazonas 793
Amapá 162
Bahia 1867
Ceará 5657
Distrito Federal 430
Espírito Santo 1734
Goiás 4110
Maranhão 1421
Minas Gerais 11812
Mato Grosso do Sul 1006
Mato Grosso 1391
Pará 1889
Paraíba 1575
Pernambuco 4019
Piauí 1665
Paraná 3745
Rio de Janeiro 1613
Rio Grande do Norte 1998
Rondônia 3102
Roraima 237
Rio Grande do Sul 5643
Santa Catarina 5372
Sergipe 413
São Paulo 8237
Tocantins 771
Name: 0, dtype: int64
Where UF
is the state name as presented in the shapefile and the series values are the values that I want to use to generate colors to fill a basemap. This is what I got so far:
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from mpl_toolkits.basemap import Basemap
import matplotlib.cm as cm
import matplotlib as mpl
from matplotlib.collections import PatchCollection
def make_map(ax):
m = Basemap(projection='merc', llcrnrlat=-35, urcrnrlat=7,
llcrnrlon=-77, urcrnrlon=-32, resolution='i', ax=ax)
m.fillcontinents()
return m
def drawstates(fig, ax, data, shapefile='../BRA_adm_shp/BRA_adm1'):
shp = m.readshapefile(shapefile, 'states', drawbounds=False)
norm = mpl.colors.Normalize(vmin=data.min(), vmax=data.max())
cmap = cm.hot
sm = cm.ScalarMappable(norm=norm, cmap=cmap)
colors = []
patches = []
for nshape, seg in enumerate(m.states):
uf = m.states_info[nshape]['NAME_1']
color = sm.to_rgba(data[uf])
poly = Polygon(seg, facecolor=color, edgecolor='white')
ax.add_patch(poly)
patches.append(poly)
colors.append(color)
p = PatchCollection(patches, cmap=cmap)
p.set_array(np.array(colors))
cb = fig.colorbar(p, ax=ax, orientation='horizontal')
fig, axes = plt.subplots(1, 2, figsize=(20, 10))
m = make_map(axes[0])
drawstates(fig, m.ax, m1)
Which leads to:
I'm not sure if this is the correct way of doing it, but I wonder how to preserve the scale of the input values, i.e., of not scaling the colorbar between 0 and 1, and how to prevent this big distance between the map and its colorbar.
回答1:
The polygons are colorized according to the ScalaMappable sm
. Hence this ScalarMappable is the one you want to give as argument to the colormap
sm = cm.ScalarMappable(norm=norm, cmap=cmap)
sm.set_array([]) # can be an empty list, only needed for matplotlib < 3.1
# ...
cb = fig.colorbar(sm, ax=ax, orientation='horizontal')
The padding between axes and colorbar can be set with the pad
argument. The default should be pad=0.15
and you will need to find a good value yourself.
来源:https://stackoverflow.com/questions/46495901/how-to-display-a-colorbar-for-a-basemap