Search code examples
pythonscatter-plot

Python - plot rectangles of known size at scatter points


I have a set of points:

a = ([126, 237, 116, 15, 136, 348, 227, 247, 106, 5, -96, 25, 146], [117, 127, 228, 107, 6, 137, 238, 16, 339, 218, 97, -4, -105])

And I make a scatter plot of them like so:

    fig = plt.figure(figsize = (15,6))
    ax = fig.add_subplot(111)
    ax.scatter(a[0], a[1], color = 'red', s=binradius)

Which makes this plot:

enter image description here

--

I am overlaying this with a picture, in which there is a spherical blobl at each of the scatter points. I want to fit this blob, so I am defining a rectangular region around the scatter points for the fit to be performed.

I want to see this rectangle on the plot, to see visually whether they are large enough to enclose the blob, like so:

enter image description here

Can I do it with scatter? Or is there any other way I can do it?


Solution

  • Although @ralf-htp's answer is nice and clean and uses scatter, as far as I know the scale of the markers is expressed in points (see e.g. here). Moreover, if you zoom in, the custom markers will not change size.

    Maybe that is just what you are looking for. If not, using separate Rectangle objects also does the trick nicely. This allows you to specify width and height in data units instead of points, and you can zoom in. If necessary, it is easy to apply a rotation as well, by setting the angle attribute:

    from matplotlib import pyplot as plt
    from matplotlib.patches import Rectangle
    
    # Your data
    a = ([126, 237, 116, 15, 136, 348, 227, 247, 106, 5, -96, 25, 146],
         [117, 127, 228, 107, 6, 137, 238, 16, 339, 218, 97, -4, -105])
    
    # Your scatter plot
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(a[0], a[1], color = 'red', s=10)
    
    # Add rectangles
    width = 30
    height = 20
    for a_x, a_y in zip(*a):
        ax.add_patch(Rectangle(
            xy=(a_x-width/2, a_y-height/2) ,width=width, height=height,
            linewidth=1, color='blue', fill=False))
    ax.axis('equal')
    plt.show()
    

    The result: scatter plot with blue rectangles

    Note: If necessary you can obtain the Rectangle instances via ax.get_children().