Matplotlib升级后自定义Arrow3D实现3D坐标轴失效的修复求助
Matplotlib升级后自定义Arrow3D实现3D坐标轴失效的修复求助
我之前写了一段代码,通过自定义Arrow3D类来在Matplotlib的3D图中添加自定义的XYZ坐标轴,还配套实现了3D标注功能和坐标轴初始化的_axesSetup函数。之前运行完全正常,但最近升级Matplotlib后,这些自定义的坐标轴突然不显示了,有没有大佬能帮忙修改一下代码让它重新正常工作?
原代码设计思路
- 让X、Y、Z轴像其他绘图元素一样添加到3D轴对象中,所以创建了继承自
FancyArrowPatch的Arrow3D类——毕竟坐标轴本质就是带箭头的线条 - 同时实现了
Annotation3D类来支持3D位置的文本标注 - 最后封装了
_axesSetup函数,用来批量设置轴范围、添加自定义坐标轴和标注,并通过setattr把这些方法绑定到Axes3D类上,方便调用
自定义Arrow3D与Annotation3D的核心代码
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d.proj3d import proj_transform from mpl_toolkits.mplot3d.axes3d import Axes3D from matplotlib.text import Annotation from matplotlib.patches import FancyArrowPatch # 创建Arrow3D类用于生成3D坐标轴箭头,继承自FancyArrowPatch class Arrow3D(FancyArrowPatch): def __init__(self, x, y, z, dx, dy, dz, *args, **kwargs): super().__init__((0,0), (0,0), *args, **kwargs) self._xyz = (x,y,z) self._dxdydz = (dx,dy,dz) def draw(self, renderer): x1,y1,z1 = self._xyz dx,dy,dz = self._dxdydz x2,y2,z2 = (x1+dx,y1+dy,z1+dz) xs, ys, zs = proj_transform((x1,x2),(y1,y2),(z1,z2), renderer.M) self.set_positions((xs[0],ys[0]),(xs[1],ys[1])) super().draw(renderer) def _arrow3D(ax, x, y, z, dx, dy, dz, *args, **kwargs): '''给Axes3D实例添加3D箭头的工具函数''' arrow = Arrow3D(x, y, z, dx, dy, dz, *args, **kwargs) ax.add_artist(arrow) # 将arrow3D方法绑定到Axes3D类,让3D轴对象可以直接调用 setattr(Axes3D,'arrow3D',_arrow3D) class Annotation3D(Annotation): def __init__(self, text, xyz, *args, **kwargs): super().__init__(text, xy=(0,0), *args, **kwargs) self._xyz = xyz def draw(self, renderer): x2, y2, z2 = proj_transform(*self._xyz, renderer.M) self.xy=(x2,y2) super().draw(renderer) def _annotate3D(ax,text, xyz, *args, **kwargs): '''给Axes3D实例添加3D文本标注的工具函数''' annotation= Annotation3D(text, xyz, *args, **kwargs) ax.add_artist(annotation) setattr(Axes3D,'annotate3D',_annotate3D)
坐标轴初始化的封装代码
import numpy as np from mpl_toolkits.mplot3d.axes3d import Axes3D def _axesSetup(ax, lX, uX, lY, uY, lZ, uZ): # 配置X轴:设置范围、添加箭头、添加标注 ax.set_xlim(lX, uX) ax.arrow3D(lX, 0, 0, uX - lX, 0, 0, mutation_scale=15, arrowstyle="-|>", color='red') ax.annotate3D('X', (uX, 0, 0), xytext=(0, 0), textcoords=('offset points'), color = 'xkcd:eggplant', weight="bold") # 配置Y轴:设置范围、添加箭头、添加标注 ax.set_ylim(lY, uY) ax.arrow3D(0, lY, 0, 0, uY - lY, 0, mutation_scale=15, arrowstyle="-|>", color='red') ax.annotate3D('Y', (0, uY, 0), xytext=(0, 0), textcoords=('offset points'), color = 'xkcd:eggplant', weight="bold") # 配置Z轴:设置范围、添加箭头、添加标注 ax.set_zlim(lZ, uZ) ax.arrow3D(0, 0, lZ, 0, 0, uZ - lZ, mutation_scale=15, arrowstyle="-|>", color='red') ax.annotate3D('Z', (0, 0, uZ), xytext=(0, 0), textcoords=('offset points'), color = 'xkcd:eggplant', weight="bold") # 将axesSetup方法绑定到Axes3D类,一键初始化自定义3D坐标轴 setattr(Axes3D, 'axesSetup', _axesSetup )
升级Matplotlib后,运行上述代码完全看不到自定义的3D坐标轴了,求各位帮忙排查修复!
备注:内容来源于stack exchange,提问作者H.Li
相关产品推荐
相关产品推荐

