如何调整散点图的标记大小,使其与给定的半径匹配? (使用 matplotlib 转换)

2023-12-08

我想让散点图的标记与数据坐标中给出的半径相匹配。

我读过pyplot散点图标记大小,标记大小以标记面积(以点^2 为单位)给出。

我尝试将给定的半径转换为点axes.transData然后通过计算面积pi * r^2,但我没有成功。

也许我的转变是错误的。 也可能是通过 VcXsrv 从 WSL 运行 matplotlib 导致了此问题。

这是我想要完成的示例代码,结果如代码下方的图像所示:

import matplotlib.pyplot as plt
from numpy import pi

n = 16
# create a n x n square with a marker at each point
x_data = []
y_data = []
for x in range(n):
    for y in range(n):
        x_data.append(x)
        y_data.append(y)

fig,ax = plt.subplots(figsize=[7,7])

# important part:
# calculate the marker size so that the markers touch

# radius in data coordinates:
r = 0.5 
# radius in display coordinates:
r_ = ax.transData.transform([r,0])[0] - ax.transData.transform([0,0])[0]
# marker size as the area of a circle
marker_size = pi * r_**2

ax.scatter(x_data, y_data, s=marker_size, edgecolors='black')

plt.show()

When I run it with s=r_ I get the result on the left and with s=marker_size I get the result on the right of the following image: Example


代码看起来非常好。如果只绘制 4 个点(n=2):

4 cricles

半径(几乎)恰好是r=0.5您想要的坐标单位。等待,almost?!是的,问题是您在绘图之前确定坐标单位到图形点的大小,所以before设置限制,这会影响坐标单位,但不会影响整体图形大小......

听起来很奇怪?也许。最重要的是,您可以使用默认轴限制((0,1) x (0,1))然后将它们放大到(-0.75, 15.75)x(-0.75, 15.75)...但是您没有减小标记大小。

所以要么将限制设置为已知大小before绘图:

ax.set_xlim((0,n-1))
ax.set_ylim((0,n-1))

完整的代码是:

import matplotlib.pyplot as plt
from numpy import pi

n = 16
# create a n x n square with a marker at each point as dummy data
x_data = []
y_data = []
for x in range(n):
    for y in range(n):
        x_data.append(x)
        y_data.append(y)

# open figure
fig,ax = plt.subplots(figsize=[7,7])
# set limits BEFORE plotting
ax.set_xlim((0,n-1))
ax.set_ylim((0,n-1))
# radius in data coordinates:
r = 0.5 # units
# radius in display coordinates:
r_ = ax.transData.transform([r,0])[0] - ax.transData.transform([0,0])[0] # points
# marker size as the area of a circle
marker_size = pi * r_**2
# plot
ax.scatter(x_data, y_data, s=marker_size, edgecolors='black')

plt.show()

output set limits

...或根据新的限制缩放标记的大小(您需要了解它们或再次进行绘图)

# plot with invisible color
ax.scatter(x_data, y_data, s=marker_size, color=(0,0,0,0))
# calculate scaling
scl = ax.get_xlim()[1] - ax.get_xlim()[0]
# plot correctly (with color)
ax.scatter(x_data, y_data, s=marker_size/scl**2, edgecolors='blue',color='red')

这是一个相当乏味的想法,因为您需要绘制数据两次,但保持轴的自动调整大小......

output with double plotting

显然还留有一些间距。这是由于对以下内容的误解area的标记。我们不是在讨论符号的面积(在本例中是圆形),而是在讨论标记的边界框(想象一下,您想要控制作为标记的星星或星号的大小......人们永远不会计算符号的实际面积)。 所以计算面积不是pi * r_**2而是一个正方形:(2*r_)**2

# open figure
fig,ax = plt.subplots(figsize=[7,7])
# setting the limits
ax.set_xlim((0,n-1))
ax.set_ylim((0,n-1))
# radius in data coordinates:
r = 0.5 # units
# radius in display coordinates:
r_ = ax.transData.transform([r,0])[0] - ax.transData.transform([0,0])[0] # points
# marker size as the area of a circle
marker_size = (2*r_)**2
# plot
ax.scatter(x_data, y_data, s=marker_size,linewidths=1)
#ax.plot(x_data, y_data, "o",markersize=2*r_)
plt.show()

output (2*r)**2 As soon as you add an edge (so a non-zero border around the markers), they will overlap: overlap

如果你使用的话会变得更加混乱plot(如果所有标记的大小都与标记的大小相同,则速度会更快docs注明为“注释”)。这markersize只是标记的宽度(不是面积):

ax.plot(x_data, y_data, "o",markersize=2*r_,color='magenta')

plot command

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何调整散点图的标记大小,使其与给定的半径匹配? (使用 matplotlib 转换) 的相关文章

随机推荐