Построение пользовательского маркера поворота в реальном времени - PullRequest
0 голосов
/ 06 мая 2020

Можно ли каким-то образом построить пользовательский маркер (например, этот ) в интерактивном режиме, но поворачивать ли он в реальном времени? Похоже, что диаграмма разброса не дает доступа к маркерам.

Real-time marker

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Я решил это с помощью переменных remove() и stati c, например:

class pltMarker:
    def __init__(self, angle=None, pathString=None):
        self.angle = angle or []
        self.pathString = pathString or """simply make and svg, open in a text editor and copy the path XML string in here"""
        self.path = parse_path( self.pathString )
        self.path.vertices -= self.path.vertices.mean( axis=0 )
        self.marker = mpl.markers.MarkerStyle( marker=self.path )
        self.marker._transform = self.marker.get_transform().rotate_deg(angle)

    def rotate(self, angle=0):
        self.marker._transform = self.marker.get_transform().rotate_deg(angle)

def animate(k):

    angle = ... # new angle
    myPltMarker.rotate(angle)

    animate.Scatter.remove()
    animate.Scatter = plt.scatter(1, 0, marker=myPltMarker.marker, s=100)

    return animate.Scatter, 

angle = ...
myPltMarker = pltMarker(angle=angle)
animatePlt.Scatter = plt.scatter(1, 0, marker=myPltMarker.marker, s=100)   

anm = animation.FuncAnimation(fig, animate, blit=False, interval=1)
plt.show()
1 голос
/ 06 мая 2020

Вы можете создать собственный маркер с FancyArrowPatch. Возможны многие стили и варианты. Такой патч нелегко обновить, но вы можете просто удалить патч и создать его снова, чтобы создать анимацию.

Самый простой способ создать анимацию - через plt.pause(), но это не работает во всех средах. Другой способ - через FuncAnimation, который включает в себя несколько дополнительных строк, но упрощает управление анимацией.

Вот пример кода для демонстрации концепций:

import matplotlib.pyplot as plt
from matplotlib import patches
from matplotlib.collections import PatchCollection
from matplotlib import animation
import numpy as np

fig, ax = plt.subplots()

N = 50
x = np.random.uniform(-20, 20, (N, 2))
dx = np.random.uniform(-1, 1, (N, 2))
dx /= np.linalg.norm(dx, axis=1, keepdims=True)
colors = plt.cm.magma(np.random.uniform(0, 1, N))

arrow_style = "Simple,head_length=2,head_width=3,tail_width=1"

ax.set_xlim(-40, 40)
ax.set_ylim(-30, 30)
ax.set_aspect('equal')

old_arrows = None

def animate(i):
    global old_arrows, x, dx

    if old_arrows is not None:
        old_arrows.remove()
    x += dx
    dx += np.random.uniform(-.1, .1, (N, 2))
    dx /= np.linalg.norm(dx, axis=1, keepdims=True)
    arrows = [patches.FancyArrowPatch((xi, yi), (xi + dxi * 10, yi + dyi * 10), arrowstyle=arrow_style)
              for (xi, yi), (dxi, dyi) in zip(x, dx)]
    old_arrows = ax.add_collection(PatchCollection(arrows, facecolors=colors))
    return old_arrows,

ani = animation.FuncAnimation(fig, animate, np.arange(1, 200),
                              interval=25, repeat=False, blit=True)
plt.show()

example plot

...