我正在使用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')
请注意,只有六个多边形可见,而应该有十个。
编辑:我知道我可以放大查看其他图片,但是我希望看到一个圆点或轮廓或其他内容而无需这样做。
编辑2 :这是一种获得所需效果的方法,方法是使用PolyCollection
绘制面部,然后使用带有标记的一系列Line2D
绘图绘制边缘,根据Patol75的答案。我的应用程序是一个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))
答案 0 :(得分: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')
您现在可以看到五个多边形,但在对数刻度下侧,会将您限制在轴的正向。
现在为您的问题提出答案。如果保持线性轴,则由于多边形大小跨越多个数量级,则将无法全部看到它们。您可以做的是在情节上添加一个艺术家,以指定其位置。这可以通过标记,箭头等来完成。如果像您所说的那样,以标记为例,则仅在看不到多边形时才希望看到该标记。对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()
答案 1 :(得分: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()