Анимированная круговая диаграмма с плотностью

#python #animation #plotly #pie-chart

#питон #Анимация #сюжетно #круговая диаграмма

Вопрос:

У меня есть следующие данные, хранящиеся в фрейме данных pandas.

 import pandas as pd
 
values = [[4500, 2500, 1053, 500],
          [872, 2389, 819, 765],
          [293, 1668, 873, 778],
          [1656, 861, 6137, 698]]

df = pd.DataFrame(values, columns=['A', 'B', 'C', 'D'])
print(df.to_markdown())
 
 Output:
|    |    A |    B |    C |   D |
|---:|-----:|-----:|-----:|----:|
|  0 | 4500 | 2500 | 1053 | 500 |
|  1 |  872 | 2389 |  819 | 765 |
|  2 |  293 | 1668 |  873 | 778 |
|  3 | 1656 |  861 | 6137 | 698 |
 

Я могу построить круговую диаграмму из одной строки, используя plotly (либо с помощью px.pie, либо go.Pie). Здесь я вывожу данные из последней строки.

 import plotly.graph_objects as go
fig = go.Figure(data=[go.Pie(labels=df.columns, values=df.iloc[-1])])
fig.show()
 

Есть ли способ создать анимированную круговую диаграмму, которая отображала бы данные из каждой строки один за другим? Похоже, что plotly express поддерживает анимацию для точечных и штриховых графиков, но я не могу найти ничего, связанного с круговыми диаграммами.
Примечание: я ищу помощи только для того, чтобы сделать это с помощью plotly. Я знаю, как это сделать с помощью matplotlib.

Комментарии:

1. Из того, что я читал на веб-страницах Plotly, следует, что анимация с помощью Plotly Express поддерживает только линейные, точечные и столбчатые чаты (а НЕ круговые диаграммы). Вы можете прочитать больше в документации по анимации Plotly и на этом форуме

Ответ №1:

Это возможно с использованием текущей версии plotly в R, я не знаю о синтаксисе python, но указание переменной «frame» при определении переменных может сработать. В R frame определяет измерение, которое изменяется в зависимости от frame, и эта функция может быть перенесена. Я добился успеха, используя это, и я получил оригинальный совет от https://plotly.com/r/animations /

Как это может выглядеть

 fig = go.Figure(data=[go.Pie(labels=df.columns, values=df.iloc[-1])]
,frame= row
)
 

Надеюсь, в том, как plotly работает на обоих языках, достаточно пересечений, чтобы это было полезно.

Ответ №2:

Ссылки

Взгляните на разделы «Простая кнопка воспроизведения» и «Использование ползунка и кнопок» из документации Plotly

Код

 import plotly.graph_objects as go
import pandas as pd
import plotly.io as pio
pio.renderers.default = 'browser'

values = [[4500, 2500, 1053, 500],
          [872, 2389, 819, 765],
          [293, 1668, 873, 778],
          [1656, 861, 6137, 698]]
headings =['A', 'B', 'C', 'D']
df = pd.DataFrame(values, columns = headings)

# create a dictionary
fig_dict = {
    "data": [],
    "layout": {},
    "frames": []
}

# create initial frame
initial_frame_values = df.iloc[0]

# add initial frame to dictionary
fig_dict["data"] = [go.Pie(labels=headings,
                           title="frame : 0",
                           values=initial_frame_values,
                           sort=False)]

# Loop through each row of df to create a list of frames 
# that will be displayed when Play button is pressed.
frames_list = []
for index, row in df.iterrows():
    current_frame_title = "frame : "   str(index 1)
    frames_list.append(
        go.Frame(data=[go.Pie(labels=headings,
                              values=row,
                              title=current_frame_title,
                              sort=False)])
    )

# create buttons for animations : Play, Pause
fig_dict["layout"]["updatemenus"] = [{
    "buttons": [{
            "args": [None, {
                "frame": {
                    "duration": 2000, # affects playback speed
                                "redraw": True
                },
                "fromcurrent": True,
                            "transition": {
                    "duration": 1000
                }
            }],
            "label": "Play",
                    "method": "animate"
        },
        {
            "args": [
                [None], {
                    "frame": {
                        "duration": 0,
                        "redraw": True
                    },
                    "mode": "immediate",
                    "transition": {
                        "duration": 0
                    }
                }
            ],
            "label": "Pause",
            "method": "animate"
        }
    ],
    "pad": {
        "r": 10,
        "t": 87
    },
    "showactive": False,
    "type": "buttons",
    "x": 0.1,
    "xanchor": "right",
    "y": 0,
    "yanchor": "top"
}]
# add our list of frames to our dictionary
fig_dict["frames"] = frames_list

# create final figure
fig = go.Figure(fig_dict)

# optional
fig_dict["layout"]["title"] = "my pie chart"
fig.update_layout(legend_title_text='stuffs')

fig.show()
 

Результат

Перед нажатием кнопки воспроизведения

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

После нажатия кнопки воспроизведения

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

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

кадр 3

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

Примечание

  • Мои изображения обрезаны и исключают кнопки воспроизведения и паузы, а также легенду.
  • Кадры 0 и 1 идентичны.
  • Перед нажатием кнопки воспроизведения отображается только кадр 0.
  • После нажатия кнопки воспроизведения будут показаны кадры 1-4, а затем анимация остановится.
  • При повторном нажатии кнопки воспроизведения снова будут отображаться кадры 1-4, а затем анимация остановится. Обратите внимание, что после этого кадр 0 опускается.