Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a matplotlib colorbar from a PatchCollection

I'm converting a Shapely MultiPolygon to a PatchCollection, and first colouring each Polygon like so:

# ldn_mp is a MultiPolygon
cm = plt.get_cmap('RdBu')
num_colours = len(ldn_mp)

fig = plt.figure()
ax = fig.add_subplot(111)
minx, miny, maxx, maxy = ldn_mp.bounds
w, h = maxx - minx, maxy - miny
ax.set_xlim(minx - 0.2 * w, maxx + 0.2 * w)
ax.set_ylim(miny - 0.2 * h, maxy + 0.2 * h)
ax.set_aspect(1)

patches = []
for poly in ldn_mp:
    colour = cm(1. * len(filter(poly.contains, points)) / num_colours)
    patches.append(PolygonPatch(poly, fc=colour, ec='#555555', lw=0.2, alpha=1., zorder=1))
pc = PatchCollection(patches, match_original=True)
ax.add_collection(pc)
ax.set_xticks([])
ax.set_yticks([])
plt.title("Density of NO$^2$ Sensors by Borough")
plt.tight_layout()
plt.show()

But I'd like to add a colorbar to my plot, based upon the PatchCollection colors. I'm not sure how to go about that; do I pass the cmap keyword when creating pc? How do I then call set_array() with the colours I've used?

like image 574
urschrei Avatar asked Sep 06 '13 12:09

urschrei


2 Answers

I had the same problem a little while ago. For each polygon I saved the corresponding color to a list named mycolors:

mycolors=[]
...
mycolors.append(SSTvalue)
path_patch = patches.PathPatch(mypath, lw=1)
mypatches.append(path_patch)

I looped over a series of multipolygons stored in a Shapefile and stored each patch in a collection. After that I plotted the polygons using the color information I had stored in the list, which was converted to an array eventually, and added a colorbar:

p = PatchCollection(mypatches, cmap=plt.get_cmap('RdYlBu_r'), alpha=1.0)
p.set_array(array(mycolors))
p.set_clim([np.ma.min(mycolors),np.ma.max(mycolors)])
plt.colorbar(p,shrink=0.5)

The full script I used to plot temperature values with colors and a colorbar for large marine ecosystems of the world represented by polygons can be found here. Hope this helps. Cheers, Trond

like image 68
Trond Kristiansen Avatar answered Oct 10 '22 03:10

Trond Kristiansen


There is no need to create an additional list. Assuming you work in pandas or numpy arrays.

For example:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
from matplotlib import cm

fig, ax = plt.subplots()
for c_l ,patches in dict_mapindex_mpl_polygon.items():
    color = df_map_elements.loc[c_l, 'stress_level']
    p = PatchCollection(patches,color=cm.Set2(color),lw=.3,edgecolor='k')
    ax.add_collection(p)
ax.autoscale_view()

p.set(array=df_map_elements['stress_level'].values, cmap='Set2')

fig.colorbar(p, label="Stress (index)")

plt.show()
like image 24
Philipp Schwarz Avatar answered Oct 10 '22 02:10

Philipp Schwarz