我有一个限制为 -1 到 1 的图。 我知道散点图不会以大小作为半径绘制,而是以大小作为点绘制。
我需要根据每个点的大小(我将其作为半径)正确缩放绘图。 修改下面的代码可以吗?
fig, ax = plt.subplots(1)
ax.set_title("Post Synaptic Neurons")
sizes = [x.size * 100 for x in post_synaptic_neurons]
offsets = [(x.origin[0],x.origin[1]) for x in post_synaptic_neurons]
print(sizes)
ax.scatter([x.origin[0] for x in post_synaptic_neurons], [x.origin[1] for x in post_synaptic_neurons],
cmap=plt.cm.hsv, s=sizes, alpha=0.5)
ax.set_xlim([-1,1])
ax.set_ylim([-1,1])
ax.set_aspect(1)
plt.tight_layout
如果没有,有人可以向我解释一下为什么 matplotlib 没有在绘图比例上绘制具有特定半径的圆的函数吗? 我没想到这是一个问题,但我的困难背后一定有充分的理由。
是的,有一种方法可以在绘图比例上绘制具有特定半径的散点图。方法是仔细定义图形大小并以点数指定半径,因为
plt.scatter
的文档表示参数 s
是“以点**2 为单位的标记大小”。
这是一个在位置 [0.5, 0.5] 处绘制半径为 0.1 的圆的示例
import matplotlib.pyplot as plt
plt.figure(figsize=[5, 5])
ax = plt.axes([0.1, 0.1, 0.8, 0.8], xlim=(0, 1), ylim=(0, 1))
points_whole_ax = 5 * 0.8 * 72 # 1 point = dpi / 72 pixels
radius = 0.1
points_radius = 2 * radius / 1.0 * points_whole_ax
ax.scatter(0.5, 0.5, s=points_radius**2, color='r')
plt.grid()
plt.show()
这里的关键是,matplotlib 中点的标准大小是每英寸 72 点 (ppi),无论 dpi 是多少。
points_radius
公式中的因子 2 来自以下事实:该面积是位于区域之外的盒子的面积,即 area = (2 * radius)**2
。输出图如下所示。
据我所知,没有高级方法可以做到这一点,但您可以使用
EllipseCollection
使其工作。由于您的数据不可用,我做了一些并编写了以下代码:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.collections import EllipseCollection
x, y = 1500 * np.random.rand(2, 100)
size = 50 + 10 * np.random.randn(100)
color = np.random.rand(100)
cmap = plt.cm.hsv
fig, ax = plt.subplots(1, 2, figsize=(16, 6),
sharex=True, sharey=True)
ax[0].scatter(x, y, s=size, c=color, cmap=cmap)
offsets = list(zip(x, y))
ax[1].add_collection(EllipseCollection(widths=size, heights=size, angles=0, units='xy',
facecolors=plt.cm.hsv(color),
offsets=offsets, transOffset=ax[1].transData))
ax[1].axis('equal') # set aspect ratio to equal
ax[1].axis([-400, 1800, -200, 1600])
如果缩放绘图,例如将轴限制更改为
ax[1].axis([200, 1000, 300, 900])
,则右侧绘图上的圆圈将根据需要缩放:
您可以在 matplotlib 文档中找到更多使用集合的示例。
该问题现有解决方案的局限性:
我已经尝试过Jordan He和jakevdp的解决方案(这个问题下面有两个答案),我发现Jordan He的解决方案仅适用于精心(手动)设计的图形尺寸。 Jakevdp 的代码是 Python-2,不适合 Python-3。
何乔丹的解决方案最大的问题是“分散”的大小仅限于圆形。也就是说,当 x 轴和 y 轴的范围不相等时,“散点”虽然看起来是圆形,但实际上在数值上是椭圆形。
我的解决方案:
总之,我参考了matplotlib关于椭圆的演示。
我使用
matplotlib.patches.Ellipse
绘制一个椭圆(以数字方式),并使其精确到我手动设置的尺寸(不是英寸,而是像轴中的值)。
这是我的代码:
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
x = 5
y = 5
e = Ellipse(xy=(x,y), width=6, height=10, angle=0) # set the width and heiget with number you want, this would be precisely numerical to the axis
fig = plt.figure(0)
# ax = fig.add_subplot(1,1,1)
ax = fig.add_subplot(1,1,1, aspect='equal') # add a plot, making the x-axis and y-axis equally looked
ax.add_artist(e)
e.set_clip_box(ax.bbox)
e.set_facecolor('#C0C0C0') # color here could be RGB like (0,0,0)
ax.set_xlim(0, 10) # set the range of x-axis
ax.set_ylim(0, 10) # set the range of y-axis
plt.grid()
plt.show()