Matplotlib обновляет позицию AnnotationBBoxPython

Программы на Python
Ответить
Anonymous
 Matplotlib обновляет позицию AnnotationBBox

Сообщение Anonymous »

Я пытаюсь отобразить метки на трехмерном графике. Моя конечная цель — отобразить крошечную версию изображения/текстуры в координатах ее среднего цвета в пространстве лаборатории.
После нескольких неудачных попыток я начал с нуля и сделал это с текстовыми аннотациями, это работает нормально, как в 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()
GPT сдался после неоднократных попыток, у меня тоже больше идей нет. Есть ли способ заставить это работать?

Подробнее здесь: https://stackoverflow.com/questions/798 ... x-position
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»