После нескольких неудачных попыток я начал с нуля и сделал это с текстовыми аннотациями, это работает нормально, как в xycoords='data', так и в xycoords='pixels':
Код: Выделить всё
from typing import cast
import matplotlib.pyplot as plt
from matplotlib.text import Annotation
from mpl_toolkits.mplot3d import Axes3D, proj3d
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
labels3d: list[tuple[float, float, float, Annotation]] = []
def update_labels3d(event):
M = cast(Axes3D, ax).get_proj()
for x, y, z, ann in labels3d:
x2, y2, _ = proj3d.proj_transform(x, y, z, M)
# px, py = ax.transData.transform((x2, y2))
# ann.set_position((px, py))
ann.set_position((x2, y2))
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d', proj_type='ortho')
ax = cast(Axes3D, ax)
ax.set_xlabel('a'); ax.set_ylabel('b'); ax.set_zlabel('L')
ax.plot([-0.5, 0.5], [0, 0], [0.5, 0.5], color='black')
ax.plot([0, 0], [-0.5, 0.5], [0.5, 0.5], color='black')
ax.plot([0, 0], [0, 0], [0, 1], color='black')
ax.set_aspect('equal')
ax.view_init(90, -90)
testpts = [[-0.4, -0.4, 0.1], [0.4, -0.4, 0.2],
[0.4, 0.4, 0.3], [-0.4, 0.4, 0.4], [0, 0, 0.5]]
for x, y, z in testpts:
ann = ax.annotate("label", (0, 0), xycoords='data') # xycoords='figure pixels'
labels3d.append((x, y, z, ann))
fig.canvas.mpl_connect('draw_event', update_labels3d)
plt.show()
Код: Выделить всё
from typing import cast
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.text import Annotation
from mpl_toolkits.mplot3d import Axes3D, proj3d
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
labels3d: list[tuple[float, float, float, AnnotationBbox]] = []
def update_labels3d(event):
M = cast(Axes3D, ax).get_proj()
for x, y, z, ab in labels3d:
x2, y2, _ = proj3d.proj_transform(x, y, z, M)
# px, py = ax.transData.transform((x2, y2))
# ab.xy = (px, py)
ab.xy = (x2, y2)
ab.stale = True
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d', proj_type='ortho')
ax = cast(Axes3D, ax)
ax.set_xlabel('a'); ax.set_ylabel('b'); ax.set_zlabel('L')
ax.plot([-0.5, 0.5], [0, 0], [0.5, 0.5], color='black')
ax.plot([0, 0], [-0.5, 0.5], [0.5, 0.5], color='black')
ax.plot([0, 0], [0, 0], [0, 1], color='black')
ax.set_aspect('equal')
ax.view_init(90, -90)
testpts = [[-0.4, -0.4, 0.1], [0.4, -0.4, 0.2],
[0.4, 0.4, 0.3], [-0.4, 0.4, 0.4], [0, 0, 0.5]]
img = np.array([[[0.0, 1.0, 1.0]]])
for x, y, z in testpts:
im = OffsetImage(img, zoom=20)
ab = AnnotationBbox(
im,
(0, 0),
xycoords='data',
# xycoords='figure pixels',
frameon=False
)
ax.add_artist(ab)
labels3d.append((x, y, z, ab))
fig.canvas.mpl_connect('draw_event', update_labels3d)
plt.show()
Подробнее здесь: https://stackoverflow.com/questions/798 ... x-position