Анимированная радарная диаграмма Python

Я пытаюсь создать радарную диаграмму с использованием Python/Matplotlib, где измеренные данные можно «воспроизвести» с помощью встроенного модуля анимации matplotlib. Я хочу, чтобы точки данных перемещались вдоль соответствующих осей по мере прохождения набора данных. У меня проблемы со чтением данных и обновлением диаграммы, и я не могу найти пример этого.

Я приложил фрагмент кода, который должен дать вам представление о том, чего я пытаюсь достичь:

import matplotlib.pyplot as plt
import matplotlib.animation as animation
from math import pi


class SubplotAnimation(animation.TimedAnimation):
    def __init__(self, data):

        self.data = data
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='polar')

        # Figure definition
        cat = ['A', 'B', 'C', 'D', 'E']
        values = [10, 10, 10, 10, 10]

        N = len(cat)

        x_as = [n / float(N) * 2 * pi for n in range(N)]

        # Because our chart will be circular we need to append a copy of
        # the first value of each list at the end of each list with data
        values += values[:1]
        x_as += x_as[:1]

        plt.rc('axes', linewidth=0.5, edgecolor='#888888')  # Set color of axes

        # Create polar plot
        ax = plt.subplot(111, projection='polar')

        # Set clockwise rotation. That is:
        ax.set_theta_offset(pi / 2)
        ax.set_theta_direction(-1)

        # Set position of y-labels
        ax.set_rlabel_position(0)

        # Set color and linestyle of grid
        ax.xaxis.grid(True, color="#888888", linestyle='solid', linewidth=0.5)
        ax.yaxis.grid(True, color="#888888", linestyle='solid', linewidth=0.5)

        # Set number of radial axes and remove labels
        plt.xticks(x_as[:-1], [])

        # Set yticks
        plt.yticks([20, 40, 60, 80, 100], ["20", "40", "60", "80", "100"])

        # Set axes limits
        plt.ylim(0, 100)

        # Draw ytick labels to make sure they fit properly
        for i in range(N):
            angle_rad = i / float(N) * 2 * pi

            if angle_rad == 0:
                ha, distance_ax = "center", 10
            elif 0 < angle_rad < pi:
                ha, distance_ax = "left", 1
            elif angle_rad == pi:
                ha, distance_ax = "center", 1
            else:
                ha, distance_ax = "right", 1

        ax.text(angle_rad, 100 + distance_ax, cat[i], size=10,
                horizontalalignment=ha, verticalalignment="center")

        animation.TimedAnimation.__init__(self, fig, interval=25, blit=True)

        def new_frame_seq(self):
            return iter(range(len(self.data)))

        def _draw_frame(self, framedata):
            ax.plot(ax, framedata)

testdata = [[10, 20, 30, 40, 50],
            [10, 20, 30, 40, 50],
            [40, 50, 60, 70, 80],
            [40, 50, 60, 70, 80],
            [50, 60, 70, 80, 90]]

ani = SubplotAnimation(testdata)
plt.show()

Любые советы о том, как сделать эту работу, будут высоко оценены!


person esvendsen    schedule 20.03.2017    source источник


Ответы (1)


Неясно, какова будет цель создания подкласса TimedAnimation. Это делает вещи слишком сложными.

Вот простой пример анимированного графика радара с использованием FuncAnimation.

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np

fig = plt.figure(figsize=(4,4))
ax = fig.add_subplot(111, projection='polar')
ax.set_ylim(0,100)

data = np.random.rand(50)*6+2
theta = np.linspace(0,2.*np.pi, num=50)
l,  = ax.plot([],[])

def update(i):
    global data
    data += (np.random.rand(50)+np.cos(i*2.*np.pi/50.))*2 
    data[-1] = data[0]
    l.set_data(theta, data )
    return l, 

ani = animation.FuncAnimation(fig, update, frames=50, interval=200, blit=True)
plt.show()

введите описание изображения здесь

person ImportanceOfBeingErnest    schedule 20.03.2017
comment
Спасибо вам большое за это! Я заставил это работать так, как я собирался в конечном итоге :-) - person esvendsen; 23.03.2017
comment
Благодарю вас ! Кажется, это здорово! Просто вопрос, я вставляю ваш код как есть. Но фигура заблокирована в первом состоянии. Другими словами, анимация не работает так, как на Notebook Jupyter. Я что-то пропустил? - person Nicoolasens; 17.12.2020
comment
Я нашел решение. Чтобы отобразить его в этой записной книжке, вам нужно добавить интерактивный виджет Javascript (представление объектов анимации в формате HTML по умолчанию), используя строки кода - person Nicoolasens; 17.12.2020