You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:14:28