【发布时间】:2021-12-13 13:38:34
【问题描述】:
我创建了一系列点,我想将其转换为补丁。
然后目标是在 y-label 的左侧绘制补丁(参见图中的红色部分),或在图中的任何其他部分绘制它。
虽然可以用 Gridspec 完成,但我想用 Patch 来完成。
import matplotlib.pyplot as plt
import numpy as np
plt.figure()
npoints = 100
td = np.linspace(np.pi*3/4, np.pi*5/4, npoints)
xd = np.cos(td)
yd = np.sin(td)
plt.plot(xd,yd)
EDIT1:
我现在可以制作补丁(只需将其移到轴外):
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.path as mpath
import matplotlib.patches as mpatches
npoints = 100
td = np.linspace(np.pi*3/4, np.pi*5/4, npoints)
xd = np.cos(td)
yd = np.sin(td)
fig, ax = plt.subplots()
ax.axis([-2, 0, -1, 1])
verts=np.c_[xd,yd]
codes = np.ones(len(xd))*2 # Path.LINETO for all points except the first
codes[0] = 1 #Path.MOVETO only for the first point
path1 = mpath.Path(verts, codes)
patch = mpatches.PathPatch(path1, facecolor='none')
ax.add_patch(patch)
结果:
现在,我只需要将它移到轴外,可能使用平移或缩放。
我确信实现它的关键在 Matplotlib Transforms tutorial 的某个地方,更具体地说,我很确定解决方案是使用 fig.transFigure。
编辑 2:快到了!
为了使用 图形坐标(在 [0,1] 之间),我对定义路径的点进行了标准化。我没有使用ax.add_patch() 向轴添加补丁,而是使用fig.add_artist() 在轴上向图形添加补丁。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.path as mpath
import matplotlib.patches as mpatches
#Normalized Data
def normalize(x):
return (x - min(x)) / (max(x) - min(x))
#plt.figure()
npoints = 100
td = np.linspace(np.pi*3/4, np.pi*5/4, npoints)
xd = np.cos(td)
yd = np.sin(td)
#plt.plot(xd,yd)
xd = normalize(xd)
yd = normalize(yd)
fig, ax = plt.subplots()
ax.axis([-2, 2, -1, 1])
verts=np.c_[xd,yd]
codes = np.ones(len(xd))*2 # Path.LINETO for all points except the first
codes[0] = 1 #Path.MOVETO only for the first point
path1 = mpath.Path(verts, codes)
patch1 = mpatches.PathPatch(path1, facecolor='none')
ax.add_patch(patch1)
patch2 = mpatches.PathPatch(path1, fc='none', ec='red', transform=fig.transFigure)
fig.add_artist(patch2)
这样做,我只需要缩放和翻译补丁,也许使用 Affine2D。
编辑 3:完成!
我终于做到了!我在scale() 和translate() 参数中使用了Try and Error,因为我没有得到它们使用的坐标系。但是,最好能得到准确的 y 中心(图坐标中的 0.5)。
完整代码如下:
import numpy as np
import matplotlib.path as mpath
import matplotlib.patches as mpatches
#Normalized Data
def normalize(x):
return (x - min(x)) / (max(x) - min(x))
npoints = 100
td = np.linspace(np.pi*3/4, np.pi*5/4, npoints)
xd = np.cos(td)
yd = np.sin(td)
xd = normalize(xd)
yd = normalize(yd)
fig, ax = plt.subplots()
ax.axis([-2, 2, -1, 1])
verts=np.c_[xd,yd]
codes = np.ones(len(xd))*2 # Path.LINETO for all points except the first
codes[0] = 1 #Path.MOVETO only for the first point
path1 = mpath.Path(verts, codes)
patch1 = mpatches.PathPatch(path1, fc='none', ec='green')
ax.add_patch(patch1) #draw inside axis
patch2 = mpatches.PathPatch(path1, fc='none', ec='C0', transform=fig.transFigure)
fig.add_artist(patch2) #this works! Draw on figure
import matplotlib.transforms as mtransforms
tt = fig.transFigure + mtransforms.Affine2D().scale(0.02, 0.8).translate(10,45)
patch3 = mpatches.PathPatch(path1, fc='none', ec='red', transform=tt)
fig.add_artist(patch3)
结果图:
【问题讨论】:
-
这个Path tutorial 可能是一个很好的帮助。
-
既然我已经完成了,我应该回答我自己的问题还是将解决方案留在问题中?
-
佩德罗,你永远不应该用答案更新问题。请恢复最后的编辑并将您的解决方案作为答案发布。 (是的,这是允许的,请参阅 Can I answer my own question?)
标签: python matplotlib plot draw patch