matplotlib - 如何绘制一个随机方向的矩形(或任何形状)?

7
我希望能够绘制一条线,并且该线的宽度是以数据单位指定的。在这种情况下,只需要执行以下操作:
plot(x, y, linewidth=1)

如果 linewidth 没有在数据单位中指定,将会失败。

为了解决这个问题,我找到了fill_between(),但是我发现这里给出的所有示例都是以下格式:

fill_between(x, y1, y2)

这意味着,x 始终由 y1y2 共享。
那么如果y1y2没有共享相同的x呢?
例如,我希望填充 line1=[(0, 0), (2, 2)]line2=[(-1, 1), (1, 3)](实际上,它们形成了一个矩形)。在这种情况下,我需要类似于以下的东西:
fill_between(x1, x2, y1, y2)

显然,这并不像预期的那样有效:
In [132]: x1 = [0,2]
   .....: x2 = [-1, 1]
   .....: y1 = [0,2]
   .....: y2 = [1,3]
   .....: fill_between(x1, x2, y1, y2)
   .....: 
Out[132]: <matplotlib.collections.PolyCollection at 0x3e5b230>

在这种情况下我应该如何绘图?

3个回答

7
更简单的是,matplotlib.patches.Rectangle
rect = matplotlib.patches.Rectangle((.25, .25), .25, .5, angle=45)
plt.gca().add_patch(rect)
plt.draw()

谢谢回答!但是这需要我计算不太好定位的矩形的角度,对吗? - user2881553
1
你知道角落在哪里,获取角度只是 np.atan2 的问题。 - tacaswell

5
好问题!我建议你不要在fill_between函数中限制自己。我总是认为深入了解事物是有益的。让我们深入Python绘图的本质。 所有matplotlib.patch对象的基础对象是Path 因此,如果掌握了Path,基本上可以以任何方式绘制所需内容。现在让我们看看如何使用神奇的Path实现你的目标。
为了获得你在问题中提到的矩形,只需要对示例进行一点调整即可。
import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches

verts = [(0., 0.), # left, bottom
         (-1., 1.), # left, top
         (1., 3.), # right, top
         (2., 2.), # right, bottom
         (0., 0.),] # ignored

codes = [Path.MOVETO,
         Path.LINETO,
         Path.LINETO,
         Path.LINETO,
         Path.CLOSEPOLY,]

path = Path(verts, codes)
fig = plt.figure()
ax = fig.add_subplot(111)
patch = patches.PathPatch(path, facecolor='orange', lw=2)
ax.add_patch(patch) 
ax.axis('equal')
plt.show()

我认为这段代码非常简单明了,不需要浪费太多言语来解释。只需复制粘贴并运行它,你将得到你想要的结果。

enter image description here


谢谢!我认为这是一个更通用的解决方案。 - user2881553

2

不必绘制线条,您可以将填充区域绘制为多边形。为此,您需要将x1x2的反转连接起来,并对y1y2执行相同的操作。像这样:

In [1]: from pylab import *
In [2]: x1 = arange(0,11,2)
In [3]: x2 = arange(0,11)
In [4]: y1 = x1**2+1
In [5]: y2 = x2**2-1
In [6]: xy = c_[r_[x1,x2[::-1]], r_[y1,y2[::-1]]]
In [7]: ax = subplot(111) # we need an axis first
In [8]: ax.add_patch(Polygon(xy))
Out[8]: <matplotlib.patches.Polygon at 0x3bff990>
In [9]: axis([0,10,-10,110]) # axis does not automatically zoom to a patch
Out[9]: [0, 10, -10, 110]
In [10]: show()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接