如何从 matplotlib 中的子图访问一个特定补丁的属性
How to access the properties of one specific patch from subplot in matplotlib
我遇到了一个关于如何从子图轴检索特定补丁对象的问题。
例如,我在一个函数中创建了一个子图,其中包含许多 patches.Polygon 个对象(我为每个对象分配了不同的标签)。在我通过 add_subplot 将此子图添加到图形后,我似乎无法访问我在子图中创建的那些 patches.Polygon 对象。
我知道我可以通过使用 findobj() 方法获取对象,但是,它只有 returns 对象的类型及其内存地址。我可以更改所有对象的颜色,但我真正需要的是通过名称或标签访问一个特定对象,例如更改一个 patches.Ploygon 而不是所有对象的颜色。
如果有人知道如何实现这一点,我将不胜感激。下面附上我的脚本。
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.gridspec as gridspec
import numpy as np
def drawEI(ax) :
# draw Endcap
x0 = np.array([0.5, 0.5, 0.5, 0.5])
y0 = np.array([0.5, 0.5, 0.5, 0.5])
step = 0.08
xy = np.zeros((2, 4))
print(xy)
# theta = [for i in range(16) : ]
theta = [345, 15, 30, 60, 75, 105, 120, 150, 165, 195, 210, 240, 255, 285, 300, 330]
nSector = 16
nEta = 4
chamberPlot = {}
for sector in range(nSector):
for eta in range(nEta):
# skip eta = 3
if eta == 2 : continue
if eta == 3 and sector%2 == 0 : continue
#if eta == 4 :
# print (sector, eta)
# x1[sector][eta] = step*(1+eta)*np.cos(np.pi*theta[sector]/360.)
# y1[sector][eta] = step*(1+eta)*np.sin(np.pi*theta[sector]/360.)
# create polygon coordinate by numpy
# xy = np.arange(8).reshape(4,2)
x1 = np.array([step * (1 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.)])
y1 = np.array([step * (1 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.)])
# print (x1+=x0,y1+=y0)
xy[0] = x1 + x0
xy[1] = y1 + y0
newxy = xy.transpose()
print(newxy.tolist())
# ax.add_patch(patches.Polygon(xy=list(zip(np.add(x1+x0),np.add(y1+y0))), fill=False))
index = sector + sector * eta
print(index)
chamberPlot[index] = patches.Polygon(newxy.tolist(), edgecolor='black', facecolor='green')
chamberPlot[index].set_label('EI_%s_%s'%(eta,sector))
# ax.add_patch(patches.Polygon(newxy.tolist(), edgecolor = 'black', facecolor = 'green'))
ax.add_patch(chamberPlot[index])
return ax
def drawEM(ax) :
# draw Endcap
x0 = np.array([0.5, 0.5, 0.5, 0.5])
y0 = np.array([0.5, 0.5, 0.5, 0.5])
step = 0.07
xy = np.zeros((2, 4))
print(xy)
# theta = [for i in range(16) : ]
theta = [345, 15, 30, 60, 75, 105, 120, 150, 165, 195, 210, 240, 255, 285, 300, 330]
nSector = 16
nEta = 5
chamberPlot = {}
for sector in range(nSector):
for eta in range(nEta):
# print (sector, eta)
# x1[sector][eta] = step*(1+eta)*np.cos(np.pi*theta[sector]/360.)
# y1[sector][eta] = step*(1+eta)*np.sin(np.pi*theta[sector]/360.)
# create polygon coordinate by numpy
# xy = np.arange(8).reshape(4,2)
x1 = np.array([step * (1 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.)])
y1 = np.array([step * (1 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.)])
# print (x1+=x0,y1+=y0)
xy[0] = x1 + x0
xy[1] = y1 + y0
newxy = xy.transpose()
print(newxy.tolist())
# ax.add_patch(patches.Polygon(xy=list(zip(np.add(x1+x0),np.add(y1+y0))), fill=False))
index = sector + sector * eta
print(index)
chamberPlot[index] = patches.Polygon(newxy.tolist(), edgecolor='black', facecolor='green')
chamberPlot[index].set_label('EM_%s_%s'%(eta,sector))
# ax.add_patch(patches.Polygon(newxy.tolist(), edgecolor = 'black', facecolor = 'green'))
ax.add_patch(chamberPlot[index])
return ax
def drawEO(ax) :
# draw Endcap
x0 = np.array([0.5, 0.5, 0.5, 0.5])
y0 = np.array([0.5, 0.5, 0.5, 0.5])
step = 0.07
xy = np.zeros((2, 4))
print(xy)
# theta = [for i in range(16) : ]
theta = [345, 15, 30, 60, 75, 105, 120, 150, 165, 195, 210, 240, 255, 285, 300, 330]
nSector = 16
nEta = 6
chamberPlot = {}
for sector in range(nSector):
for eta in range(nEta):
# print (sector, eta)
# x1[sector][eta] = step*(1+eta)*np.cos(np.pi*theta[sector]/360.)
# y1[sector][eta] = step*(1+eta)*np.sin(np.pi*theta[sector]/360.)
# create polygon coordinate by numpy
# xy = np.arange(8).reshape(4,2)
x1 = np.array([step * (1 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.)])
y1 = np.array([step * (1 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.)])
# print (x1+=x0,y1+=y0)
xy[0] = x1 + x0
xy[1] = y1 + y0
newxy = xy.transpose()
print(newxy.tolist())
# ax.add_patch(patches.Polygon(xy=list(zip(np.add(x1+x0),np.add(y1+y0))), fill=False))
index = sector + sector * eta
print(index)
chamberPlot[index] = patches.Polygon(newxy.tolist(), edgecolor='black', facecolor='green')
chamberPlot[index].set_label('EO_%s_%s'%(eta,sector))
# ax.add_patch(patches.Polygon(newxy.tolist(), edgecolor = 'black', facecolor = 'green'))
ax.add_patch(chamberPlot[index])
return ax
fig = plt.figure(constrained_layout=False)
spec2 = gridspec.GridSpec(ncols=2, nrows=2, figure=fig)
axEM = fig.add_subplot(spec2[1,0])
axEM.set_xticklabels([])
axEM.set_yticklabels([])
axEM.axis('off')
axEM = drawEM(axEM)
axEO = fig.add_subplot(spec2[0,1])
axEO.set_xticklabels([])
axEO.set_yticklabels([])
axEO.axis('off')
axEO = drawEO(axEO)
axEI = fig.add_subplot(spec2[0,0])
axEI.set_xticklabels([])
axEI.set_yticklabels([])
axEI.axis('off')
axEI = drawEI(axEI)
objs = axEI.findobj(patches.Polygon)
print (objs)
for obj in objs :
#print (obj.label())
obj.set_facecolor('red') # this is ok
plt.subplots_adjust(wspace=0, hspace=0)
plt.show()
我的问题是如何更改子图 axEM 中一个特定 ploygon 'BM_2_5' 的面部颜色?
使用轴对象和你的补丁的索引,你可以这样实现你想要的:
import matplotlib.pyplot as plt
import matplotlib.patches as ptc
import numpy as np
fig, ax = plt.subplots()
pCol = ['red', 'blue']
for i in range(2):
ax.add_patch(ptc.Polygon(np.random.rand(3, 2), fc=pCol[i]))
ax.patches[0].set_facecolor((0, 1, 0, 1))
plt.show()
注意没有绘制红色多边形。
编辑:考虑到您的评论
import matplotlib.pyplot as plt
import matplotlib.patches as ptc
import numpy as np
fig, ax = plt.subplots()
pLab = ['First', 'Second']
pCol = ['red', 'blue']
for i in range(2):
ax.add_patch(ptc.Polygon(np.random.rand(3, 2), fc=pCol[i], label=pLab[i]))
for patch in ax.patches:
if patch.get_label() == 'First':
patch.set_facecolor('green')
plt.show()
编辑:从函数返回轴应该没问题。
import matplotlib.pyplot as plt
import matplotlib.patches as ptc
import numpy as np
def drawPatches(ax):
for i in range(2):
ax.add_patch(ptc.Polygon(np.random.rand(3, 2), fc=pCol[i],
label=pLab[i]))
return ax
fig, ax = plt.subplots()
pLab = ['First', 'Second']
pCol = ['red', 'blue']
ax = drawPatches(ax)
for patch in ax.patches:
if patch.get_label() == 'First':
patch.set_facecolor('green')
plt.show()
我遇到了一个关于如何从子图轴检索特定补丁对象的问题。 例如,我在一个函数中创建了一个子图,其中包含许多 patches.Polygon 个对象(我为每个对象分配了不同的标签)。在我通过 add_subplot 将此子图添加到图形后,我似乎无法访问我在子图中创建的那些 patches.Polygon 对象。 我知道我可以通过使用 findobj() 方法获取对象,但是,它只有 returns 对象的类型及其内存地址。我可以更改所有对象的颜色,但我真正需要的是通过名称或标签访问一个特定对象,例如更改一个 patches.Ploygon 而不是所有对象的颜色。 如果有人知道如何实现这一点,我将不胜感激。下面附上我的脚本。
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.gridspec as gridspec
import numpy as np
def drawEI(ax) :
# draw Endcap
x0 = np.array([0.5, 0.5, 0.5, 0.5])
y0 = np.array([0.5, 0.5, 0.5, 0.5])
step = 0.08
xy = np.zeros((2, 4))
print(xy)
# theta = [for i in range(16) : ]
theta = [345, 15, 30, 60, 75, 105, 120, 150, 165, 195, 210, 240, 255, 285, 300, 330]
nSector = 16
nEta = 4
chamberPlot = {}
for sector in range(nSector):
for eta in range(nEta):
# skip eta = 3
if eta == 2 : continue
if eta == 3 and sector%2 == 0 : continue
#if eta == 4 :
# print (sector, eta)
# x1[sector][eta] = step*(1+eta)*np.cos(np.pi*theta[sector]/360.)
# y1[sector][eta] = step*(1+eta)*np.sin(np.pi*theta[sector]/360.)
# create polygon coordinate by numpy
# xy = np.arange(8).reshape(4,2)
x1 = np.array([step * (1 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.)])
y1 = np.array([step * (1 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.)])
# print (x1+=x0,y1+=y0)
xy[0] = x1 + x0
xy[1] = y1 + y0
newxy = xy.transpose()
print(newxy.tolist())
# ax.add_patch(patches.Polygon(xy=list(zip(np.add(x1+x0),np.add(y1+y0))), fill=False))
index = sector + sector * eta
print(index)
chamberPlot[index] = patches.Polygon(newxy.tolist(), edgecolor='black', facecolor='green')
chamberPlot[index].set_label('EI_%s_%s'%(eta,sector))
# ax.add_patch(patches.Polygon(newxy.tolist(), edgecolor = 'black', facecolor = 'green'))
ax.add_patch(chamberPlot[index])
return ax
def drawEM(ax) :
# draw Endcap
x0 = np.array([0.5, 0.5, 0.5, 0.5])
y0 = np.array([0.5, 0.5, 0.5, 0.5])
step = 0.07
xy = np.zeros((2, 4))
print(xy)
# theta = [for i in range(16) : ]
theta = [345, 15, 30, 60, 75, 105, 120, 150, 165, 195, 210, 240, 255, 285, 300, 330]
nSector = 16
nEta = 5
chamberPlot = {}
for sector in range(nSector):
for eta in range(nEta):
# print (sector, eta)
# x1[sector][eta] = step*(1+eta)*np.cos(np.pi*theta[sector]/360.)
# y1[sector][eta] = step*(1+eta)*np.sin(np.pi*theta[sector]/360.)
# create polygon coordinate by numpy
# xy = np.arange(8).reshape(4,2)
x1 = np.array([step * (1 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.)])
y1 = np.array([step * (1 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.)])
# print (x1+=x0,y1+=y0)
xy[0] = x1 + x0
xy[1] = y1 + y0
newxy = xy.transpose()
print(newxy.tolist())
# ax.add_patch(patches.Polygon(xy=list(zip(np.add(x1+x0),np.add(y1+y0))), fill=False))
index = sector + sector * eta
print(index)
chamberPlot[index] = patches.Polygon(newxy.tolist(), edgecolor='black', facecolor='green')
chamberPlot[index].set_label('EM_%s_%s'%(eta,sector))
# ax.add_patch(patches.Polygon(newxy.tolist(), edgecolor = 'black', facecolor = 'green'))
ax.add_patch(chamberPlot[index])
return ax
def drawEO(ax) :
# draw Endcap
x0 = np.array([0.5, 0.5, 0.5, 0.5])
y0 = np.array([0.5, 0.5, 0.5, 0.5])
step = 0.07
xy = np.zeros((2, 4))
print(xy)
# theta = [for i in range(16) : ]
theta = [345, 15, 30, 60, 75, 105, 120, 150, 165, 195, 210, 240, 255, 285, 300, 330]
nSector = 16
nEta = 6
chamberPlot = {}
for sector in range(nSector):
for eta in range(nEta):
# print (sector, eta)
# x1[sector][eta] = step*(1+eta)*np.cos(np.pi*theta[sector]/360.)
# y1[sector][eta] = step*(1+eta)*np.sin(np.pi*theta[sector]/360.)
# create polygon coordinate by numpy
# xy = np.arange(8).reshape(4,2)
x1 = np.array([step * (1 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.cos(np.pi * theta[(sector + 1) % 16] / 180.)])
y1 = np.array([step * (1 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[sector] / 180.),
step * (2 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.),
step * (1 + eta) * np.sin(np.pi * theta[(sector + 1) % 16] / 180.)])
# print (x1+=x0,y1+=y0)
xy[0] = x1 + x0
xy[1] = y1 + y0
newxy = xy.transpose()
print(newxy.tolist())
# ax.add_patch(patches.Polygon(xy=list(zip(np.add(x1+x0),np.add(y1+y0))), fill=False))
index = sector + sector * eta
print(index)
chamberPlot[index] = patches.Polygon(newxy.tolist(), edgecolor='black', facecolor='green')
chamberPlot[index].set_label('EO_%s_%s'%(eta,sector))
# ax.add_patch(patches.Polygon(newxy.tolist(), edgecolor = 'black', facecolor = 'green'))
ax.add_patch(chamberPlot[index])
return ax
fig = plt.figure(constrained_layout=False)
spec2 = gridspec.GridSpec(ncols=2, nrows=2, figure=fig)
axEM = fig.add_subplot(spec2[1,0])
axEM.set_xticklabels([])
axEM.set_yticklabels([])
axEM.axis('off')
axEM = drawEM(axEM)
axEO = fig.add_subplot(spec2[0,1])
axEO.set_xticklabels([])
axEO.set_yticklabels([])
axEO.axis('off')
axEO = drawEO(axEO)
axEI = fig.add_subplot(spec2[0,0])
axEI.set_xticklabels([])
axEI.set_yticklabels([])
axEI.axis('off')
axEI = drawEI(axEI)
objs = axEI.findobj(patches.Polygon)
print (objs)
for obj in objs :
#print (obj.label())
obj.set_facecolor('red') # this is ok
plt.subplots_adjust(wspace=0, hspace=0)
plt.show()
我的问题是如何更改子图 axEM 中一个特定 ploygon 'BM_2_5' 的面部颜色?
使用轴对象和你的补丁的索引,你可以这样实现你想要的:
import matplotlib.pyplot as plt
import matplotlib.patches as ptc
import numpy as np
fig, ax = plt.subplots()
pCol = ['red', 'blue']
for i in range(2):
ax.add_patch(ptc.Polygon(np.random.rand(3, 2), fc=pCol[i]))
ax.patches[0].set_facecolor((0, 1, 0, 1))
plt.show()
注意没有绘制红色多边形。
编辑:考虑到您的评论
import matplotlib.pyplot as plt
import matplotlib.patches as ptc
import numpy as np
fig, ax = plt.subplots()
pLab = ['First', 'Second']
pCol = ['red', 'blue']
for i in range(2):
ax.add_patch(ptc.Polygon(np.random.rand(3, 2), fc=pCol[i], label=pLab[i]))
for patch in ax.patches:
if patch.get_label() == 'First':
patch.set_facecolor('green')
plt.show()
编辑:从函数返回轴应该没问题。
import matplotlib.pyplot as plt
import matplotlib.patches as ptc
import numpy as np
def drawPatches(ax):
for i in range(2):
ax.add_patch(ptc.Polygon(np.random.rand(3, 2), fc=pCol[i],
label=pLab[i]))
return ax
fig, ax = plt.subplots()
pLab = ['First', 'Second']
pCol = ['red', 'blue']
ax = drawPatches(ax)
for patch in ax.patches:
if patch.get_label() == 'First':
patch.set_facecolor('green')
plt.show()