Search code examples
pythonmatplotlibpixel

How can I get the pixel colors in matplotlib?


I am plotting a collection of rectangles with matplotlib.patches. My code is:

import matplotlib.pyplot as plt
import matplotlib.patches as patches

fig = plt.figure(figsize=(14, 10))

for i in rectangles_list:

    ax1 = fig.add_subplot(111, aspect='equal')
    ax1.add_patch(patches.Rectangle(
                 (x[i], y[i]),
                  width[i],
                  height[i],
                  alpha = 1.0,
                  facecolor = colors_list[i]
                 )
                 )

plt.show()

The rectangles may be overlapping, therefore some of them may be completely hidden. Do you know if it is possible to get the colors of the visible rectangles? I mean the colors of the rectangles that are not completely hidden and therefore that can be actually viewed by the user. I was thinking to some function that returns the color of the pixels, but more intelligent ideas are welcome. If possible, I'd prefer to not use PIL. Unfortunately I cannot find any solution on the internet.


Solution

  • Following Vlass Sokolov comment and this Stackoverflow post by Joe Kington, here is how you could get a numpy array containing all the unique colors that are visible on a matplotlib figure:

    import matplotlib.pyplot as plt
    from matplotlib.patches import Rectangle
    import numpy as np
    
    plt.close('all')
    
    # Generate some data :
    
    N = 1000
    x, y = np.random.rand(N), np.random.rand(N)
    w, h = np.random.rand(N)/10 + 0.05, np.random.rand(N)/10 + 0.05
    colors = np.vstack([np.random.random_integers(0, 255, N),
                        np.random.random_integers(0, 255, N),
                        np.random.random_integers(0, 255, N)]).T
    
    # Plot and draw the data :
    
    fig = plt.figure(figsize=(7, 7), facecolor='white')
    ax = fig.add_subplot(111, aspect='equal')
    for i in range(N):
        ax.add_patch(Rectangle((x[i], y[i]), w[i], h[i], fc=colors[i]/255., ec='none'))
    ax.axis([0, 1, 0, 1])
    ax.axis('off')
    fig.canvas.draw()
    
    # Save data in a rgb string and convert to numpy array :
    
    rgb_data = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')
    rgb_data = rgb_data.reshape((int(len(rgb_data)/3), 3))
    
    # Keep only unique colors :
    
    rgb_data = np.vstack({tuple(row) for row in rgb_data})
    
    # Show and save figure :
    
    fig.savefig('rectangle_colors.png')
    plt.show()
    

    enter image description here