Search code examples
pythonmatplotlibpatchcolorbar

How to add a colorbar for iteratively added patches?


I am iteratively adding rectangular patches to a plot that are coloured according to a sensor reading. How would I go about adding a colorbar to my plot based on these values? Given that these patches are not stored in an array, I expect I need to define a colorbar spanning a range of values independently of what is being plotted. How would I do this?


Solution

  • You can create a colorbar from a ScalarMappable, given a colormap and a norm. The norm needs the minimum and maximum of the values and projects input values to the range 0,1.

    The code below uses a generator to simulate reading the measurements. A norm is created for input values between 0 and 20. relim and autoscale_view make sure the ax's limits are recalculated for each new rectangle.

    import matplotlib.pyplot as plt
    from matplotlib.patches import Rectangle
    import numpy as np
    
    def get_next_data():
        for i in range(20):
            value = np.random.uniform(0, 20)
            x = np.random.uniform(0, 30)
            y = np.random.uniform(0, 10)
            yield x, y, value
    
    fig, ax = plt.subplots()
    minv, maxv = 0, 20
    cmap = plt.cm.coolwarm
    norm = plt.Normalize(minv, maxv)
    sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
    sm.set_array([])
    plt.colorbar(sm, ax=ax, label='Values')
    for x, y, val in get_next_data():
        patch = Rectangle((x, y), 1, 1, color=cmap(norm(val)))
        ax.add_patch(patch)
        x += 1
        ax.relim()
        ax.autoscale_view()
        plt.pause(1)
    plt.show()
    

    example plot