当多边形变得太小时,带有polycollection的绘图会消失

问题描述 投票:7回答:2

我正在使用PolyCollection绘制各种尺寸的数据。有时候多边形非常小。如果它们太小,它们根本就不会被绘制。我希望大纲至少能够显示出来,这样你才能知道有些数据存在。有没有设置来控制这个?

这里是一些重现问题的代码,以及输出图像:

import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection
from matplotlib import colors

fig = plt.figure()
ax = fig.add_subplot(111)
verts = []

edge_col = colors.colorConverter.to_rgb('lime')
face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

for i in range(10):
    w = 0.5 * 10**(-i)
    xs = [i - w, i - w, i + w, i - w]
    ys = [-w, w, 0, -w]

    verts.append(list(zip(xs, ys)))

ax.set_xlim(-1, 11)
ax.set_ylim(-2, 2)

ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

plt.savefig('out.png')

out

请注意,只有六个多边形可见,而应该有十个。

编辑:我知道我可以放大以查看其他人,但我希望看到一个点或大纲或其他东西而不这样做。

编辑2:这是一种获得所需效果的方法,通过使用PolyCollection绘制面,然后根据Patol75的答案使用带标记的一系列Line2D图绘制边缘。我的应用程序是一个带有大量多边形的matplotlib动画,所以我更愿意避免使用Line2D来提高效率,如果我不需要两次绘制东西就会更清洁,所以我仍然希望得到更好的答案。

ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=None, facecolor=face_col, zorder=1))

for pts in verts:
    ax.add_line(Line2D([pt[0] for pt in pts], [pt[1] for pt in pts], lw=3, alpha=0.5, color=edge_col,
                                 marker='.', ms=1, mec=edge_col, solid_capstyle='projecting', zorder=2))

out_line2d

python matplotlib
2个回答
2
投票

缩放您的绘图窗口,您会注意到正在绘制剩余的两个多边形。它们太小了,你无法看到它们。确信这一点的一种方法是更换

ax.set_xlim(-1, 6)
ax.set_ylim(-2, 2)

通过

ax.set_xlim(1e-1, 1e1)
ax.set_ylim(1e-5, 1e0)
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_aspect('equal')

现在可以看到您的五个多边形,但在下方,对数刻度将您限制在轴的正侧。 enter image description here 现在提出你的问题的答案。如果保持线性轴,当多边形大小跨越多个数量级时,您将无法全部看到它们。你可以做的是在你的情节上添加一个指定其位置的艺术家。这可以用标记,箭头等来完成......如果我们以标记为例,如你所说,我们只想看到这个标记,如果我们看不到多边形。 plot()调用中的关键字zorder允许指定哪个艺术家应该具有图中的显示优先级。请考虑以下示例。

import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection
fig = plt.figure()
ax = fig.add_subplot(111)
verts = []
for i in range(5):
    w = 0.5 * 10**(-i)
    xs = [i - w, i - w, i + w, i + w, i - w]
    ys = [-w, w, w, -w, -w]
    ax.plot((xs[2] + xs[1]) / 2, (ys[1] + ys[0]) / 2, linestyle='none',
            marker='o', color='xkcd:crimson',  markersize=1, zorder=-1)
    verts.append(list(zip(xs, ys)))
ax.set_xlim(-1, 6)
ax.set_ylim(-2, 2)
poly = PolyCollection(verts, lw=5, edgecolor='black', facecolor='gray')
ax.add_collection(poly)
plt.show()

生产enter image description here 您会注意到,如果放大matplotlib图中的最后两个点,您实际上看不到标记,而是多边形。


1
投票

您可以介绍一些最小单位minw,这是形状可以拥有的最小尺寸。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection
from matplotlib import colors

fig = plt.figure()
ax = fig.add_subplot(111)
verts = []

edge_col = colors.colorConverter.to_rgb('lime')
face_col = [(2.0 + val) / 3.0 for val in edge_col] # a little lighter

ax.set_xlim(-1, 11)
ax.set_ylim(-2, 2)

u = np.diff(np.array([ax.get_xlim(), ax.get_ylim()]), axis=1).min()
px = np.max(fig.get_size_inches())*fig.dpi
minw = u/px/2

for i in range(10):
    w = 0.5 * 10**(-i)
    if w < minw:
        w = minw
    xs = [i - w, i - w, i + w, i - w]
    ys = [-w, w, 0, -w]

    verts.append(list(zip(xs, ys)))


ax.add_collection(PolyCollection(verts, lw=3, alpha=0.5, edgecolor=edge_col, facecolor=face_col))

plt.savefig('out.png')
plt.show()

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.