Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 751
SuperCiocia Avatar asked Aug 28 '18 11:08

SuperCiocia


2 Answers

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().

like image 51
djvg Avatar answered Oct 04 '22 15:10

djvg


you can define the markers in the verts option of matplotlib.pyplot.scatter like in Understanding matplotlib verts and https://matplotlib.org/gallery/lines_bars_and_markers/scatter_custom_symbol.html

verts : sequence of (x, y), optional

If marker is None [ this is not entirely working, cf Understanding matplotlib verts ], these vertices will be used to construct the marker. The center of the marker is located at (0, 0) in normalized units. The overall marker is rescaled by s.

source : https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html

However i am not sure how to define exactly the markers you painted, you have to construct a list that contains the desired marker pixel by pixel

rectangle with verts :

verts = list(zip([-10.,10.,10.,-10],[-5.,-5.,5.,5]))
ax.scatter([0.5,1.0],[1.0,2.0], marker=(verts,0))

source : Understanding matplotlib verts

like image 35
ralf htp Avatar answered Oct 04 '22 15:10

ralf htp