Note

Go to the endto download the full example code.

Menu#

Using texts to construct a simple menu.

menu
fromdataclassesimportdataclassimportmatplotlib.pyplotaspltimportmatplotlib.artistasartistimportmatplotlib.patchesaspatchesfrommatplotlib.typingimportColorType@dataclassclassItemProperties:fontsize:float=14labelcolor:ColorType='black'bgcolor:ColorType='yellow'alpha:float=1.0classMenuItem(artist.Artist):padx=0.05# inchespady=0.05def__init__(self,fig,labelstr,props=None,hoverprops=None,on_select=None):super().__init__()self.set_figure(fig)self.labelstr=labelstrself.props=propsifpropsisnotNoneelseItemProperties()self.hoverprops=(hoverpropsifhoverpropsisnotNoneelseItemProperties())ifself.props.fontsize!=self.hoverprops.fontsize:raiseNotImplementedError('support for different font sizes not implemented')self.on_select=on_select# specify coordinates in inches.self.label=fig.text(0,0,labelstr,transform=fig.dpi_scale_trans,size=props.fontsize)self.text_bbox=self.label.get_window_extent(fig.canvas.get_renderer())self.text_bbox=fig.dpi_scale_trans.inverted().transform_bbox(self.text_bbox)self.rect=patches.Rectangle((0,0),1,1,transform=fig.dpi_scale_trans)# Will be updated later.self.set_hover_props(False)fig.canvas.mpl_connect('button_release_event',self.check_select)defcheck_select(self,event):over,_=self.rect.contains(event)ifnotover:returnifself.on_selectisnotNone:self.on_select(self)defset_extent(self,x,y,w,h,depth):self.rect.set(x=x,y=y,width=w,height=h)self.label.set(position=(x+self.padx,y+depth+self.pady/2))self.hover=Falsedefdraw(self,renderer):self.rect.draw(renderer)self.label.draw(renderer)defset_hover_props(self,b):props=self.hoverpropsifbelseself.propsself.label.set(color=props.labelcolor)self.rect.set(facecolor=props.bgcolor,alpha=props.alpha)defset_hover(self,event):"""        Update the hover status of event and return whether it was changed.        """b,_=self.rect.contains(event)changed=(b!=self.hover)ifchanged:self.set_hover_props(b)self.hover=breturnchangedclassMenu:def__init__(self,fig,menuitems):self.figure=figself.menuitems=menuitemsmaxw=max(item.text_bbox.widthforiteminmenuitems)maxh=max(item.text_bbox.heightforiteminmenuitems)depth=max(-item.text_bbox.y0foriteminmenuitems)x0=1y0=4width=maxw+2*MenuItem.padxheight=maxh+MenuItem.padyforiteminmenuitems:left=x0bottom=y0-maxh-MenuItem.padyitem.set_extent(left,bottom,width,height,depth)fig.artists.append(item)y0-=maxh+MenuItem.padyfig.canvas.mpl_connect('motion_notify_event',self.on_move)defon_move(self,event):ifany(item.set_hover(event)foriteminself.menuitems):self.figure.canvas.draw()fig=plt.figure()fig.subplots_adjust(left=0.3)props=ItemProperties(labelcolor='black',bgcolor='yellow',fontsize=15,alpha=0.2)hoverprops=ItemProperties(labelcolor='white',bgcolor='blue',fontsize=15,alpha=0.2)menuitems=[]forlabelin('open','close','save','save as','quit'):defon_select(item):print(f'you selected{item.labelstr}')item=MenuItem(fig,label,props=props,hoverprops=hoverprops,on_select=on_select)menuitems.append(item)menu=Menu(fig,menuitems)plt.show()

Gallery generated by Sphinx-Gallery