我已经调整了进口税的答案,以便与配送和班级合作。 特征:
- The entire framework is contained inside of a single class, so all of the used variables are only available within their relevant scopes.
- Can create multiple distinct sets of patches
- Hovering over a patch prints patch collection name and patch subname
- Hovering over a patch highlights all patches of that collection by changing their edge color to black
注:对我的申请而言,重叠无关紧要,因此当时只显示一个物体的名称。 如果你愿意,可以自由延伸到多个物体,这并非太困难。
<>Usage
fig, ax = plt.subplots(tight_layout=True)
ap = annotated_patches(fig, ax)
ap.add_patches( Azure , circle , blue , np.random.uniform(0, 1, (4,2)), ABCD , 0.1)
ap.add_patches( Lava , rect , red , np.random.uniform(0, 1, (3,2)), EFG , 0.1, 0.05)
ap.add_patches( Emerald , rect , green , np.random.uniform(0, 1, (3,2)), HIJ , 0.05, 0.1)
plt.axis( equal )
plt.axis( off )
plt.show()
<>执行>
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.collections import PatchCollection
np.random.seed(1)
class annotated_patches:
def __init__(self, fig, ax):
self.fig = fig
self.ax = ax
self.annot = self.ax.annotate("", xy=(0,0),
xytext=(20,20),
textcoords="offset points",
bbox=dict(boxstyle="round", fc="w"),
arrowprops=dict(arrowstyle="->"))
self.annot.set_visible(False)
self.collectionsDict = {}
self.coordsDict = {}
self.namesDict = {}
self.isActiveDict = {}
self.motionCallbackID = self.fig.canvas.mpl_connect("motion_notify_event", self.hover)
def add_patches(self, groupName, kind, color, xyCoords, names, *params):
if kind== circle :
circles = [mpatches.Circle(xy, *params, ec="none") for xy in xyCoords]
thisCollection = PatchCollection(circles, facecolor=color, alpha=0.5, edgecolor=None)
ax.add_collection(thisCollection)
elif kind == rect :
rectangles = [mpatches.Rectangle(xy, *params, ec="none") for xy in xyCoords]
thisCollection = PatchCollection(rectangles, facecolor=color, alpha=0.5, edgecolor=None)
ax.add_collection(thisCollection)
else:
raise ValueError( Unexpected kind , kind)
self.collectionsDict[groupName] = thisCollection
self.coordsDict[groupName] = xyCoords
self.namesDict[groupName] = names
self.isActiveDict[groupName] = False
def update_annot(self, groupName, patchIdxs):
self.annot.xy = self.coordsDict[groupName][patchIdxs[0]]
self.annot.set_text(groupName + : + self.namesDict[groupName][patchIdxs[0]])
# Set edge color
self.collectionsDict[groupName].set_edgecolor( black )
self.isActiveDict[groupName] = True
def hover(self, event):
vis = self.annot.get_visible()
updatedAny = False
if event.inaxes == self.ax:
for groupName, collection in self.collectionsDict.items():
cont, ind = collection.contains(event)
if cont:
self.update_annot(groupName, ind["ind"])
self.annot.set_visible(True)
self.fig.canvas.draw_idle()
updatedAny = True
else:
if self.isActiveDict[groupName]:
collection.set_edgecolor(None)
self.isActiveDict[groupName] = True
if (not updatedAny) and vis:
self.annot.set_visible(False)
self.fig.canvas.draw_idle()