The easiest way is to use PatchCollection and pass in your "z" (ie the values you want to mark) as array kwarg.
As a simple example:
import itertools import matplotlib.pyplot as plt from matplotlib.patches import Rectangle from matplotlib.collections import PatchCollection import numpy as np def main(): fig = plt.figure() ax = fig.add_subplot(111, projection='polar') x = np.radians(np.arange(0, 360, 10)) y = np.random.random(x.size) z = np.random.random(y.size) cmap = plt.get_cmap('cool') coll = colored_bar(x, y, z, ax=ax, width=np.radians(10), cmap=cmap) fig.colorbar(coll) ax.set_yticks([0.5, 1.0]) plt.show() def colored_bar(left, height, z=None, width=0.8, bottom=0, ax=None, **kwargs): if ax is None: ax = plt.gca() width = itertools.cycle(np.atleast_1d(width)) bottom = itertools.cycle(np.atleast_1d(bottom)) rects = [] for x, y, h, w in zip(left, bottom, height, width): rects.append(Rectangle((x,y), w, h)) coll = PatchCollection(rects, array=z, **kwargs) ax.add_collection(coll) ax.autoscale() return coll if __name__ == '__main__': main()

If you need a discrete color map, the easiest way is to specify the number of intervals you want when you call plt.get_cmap . For example, in the above code, if you replace the line cmap = plt.get_cmap('cool') with:
cmap = plt.get_cmap('cool', 5)
Then you get a discrete color palette with 5 intervals. (Alternatively, you can pass the ListedColormap that you created in your example.)

If you want a “fully functional” draw chart function, you can do something like this:
import itertools import matplotlib.pyplot as plt from matplotlib.patches import Rectangle from matplotlib.collections import PatchCollection import numpy as np def main(): azi = np.random.normal(20, 30, 100) z = np.cos(np.radians(azi + 45)) plt.figure(figsize=(5,6)) plt.subplot(111, projection='polar') coll = rose(azi, z=z, bidirectional=True) plt.xticks(np.radians(range(0, 360, 45)), ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']) plt.colorbar(coll, orientation='horizontal') plt.xlabel('A rose diagram colored by a second variable') plt.rgrids(range(5, 20, 5), angle=290) plt.show() def rose(azimuths, z=None, ax=None, bins=30, bidirectional=False, color_by=np.mean, **kwargs): """Create a "rose" diagram (aka circular histogram). Parameters: ----------- azimuths: sequence of numbers The observed azimuths in degrees. z: sequence of numbers (optional) A second, co-located variable to color the plotted rectangles by. ax: a matplotlib Axes (optional) The axes to plot on. Defaults to the current axes. bins: int or sequence of numbers (optional) The number of bins or a sequence of bin edges to use. bidirectional: boolean (optional) Whether or not to treat the observed azimuths as bi-directional measurements (ie if True, 0 and 180 are identical). color_by: function or string (optional) A function to reduce the binned z values with. Alternately, if the string "count" is passed in, the displayed bars will be colored by their y-value (the number of azimuths measurements in that bin). Additional keyword arguments are passed on to PatchCollection. Returns: -------- A matplotlib PatchCollection """ azimuths = np.asanyarray(azimuths) if color_by == 'count': z = np.ones_like(azimuths) color_by = np.sum if ax is None: ax = plt.gca() ax.set_theta_direction(-1) ax.set_theta_offset(np.radians(90)) if bidirectional: other = azimuths + 180 azimuths = np.concatenate([azimuths, other]) if z is not None: z = np.concatenate([z, z])
