Трехмерный анимированный линейный сюжет с графикой на питоне

Я видел этот 3D сюжет. он был анимирован и добавлял новое значение каждый день. я не нашел пример, чтобы воссоздать его с помощью сюжета в python.

График должен начинаться со значения из первой строки (100). Начальное значение должно остаться (без скользящих значений). График должен быть анимирован таким образом, чтобы каждое значение строки добавлялось одно за другим, а ось x расширялась. следующий фрейм данных содержит значения (df_stocks) и даты для построения графика. назначение цветов было бы отличным дополнением. чем больше положительного, тем глубже зеленый, чем больше отрицательного, тем темнее красный.

import yfinance as yf
import pandas as pd

stocks = ["AAPL", "MSFT"]

df_stocks = pd.DataFrame()
for stock in stocks:
    df = yf.download(stock, start = "2022-01-01", end = "2022-07-01", group_by='ticker')
    df['perct'] = df['Close'].pct_change()
    df_stocks[stock] = df['perct']

df_stocks.iloc[0] = 0
df_stocks += 1
df_stocks = df_stocks.cumprod()*100
df_stocks -= 100 
Потяните за рычаг выброса энергососущих проектов
Потяните за рычаг выброса энергососущих проектов
На этой неделе моя команда отменила проект, над которым я работал. Неделя усилий пошла насмарку.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
1
0
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать список go.Frame объектов, как показано в этом примере. Поскольку вы хотите, чтобы линейный график постоянно расширялся наружу, каждый кадр должен включать данные, которые на одну строку длиннее, чем предыдущий кадр, поэтому мы можем использовать понимание списка, например:

frames = [go.Frame(data=

    ## ...extract info from df_stocks.iloc[:i]

for i in range(len(df_stocks))]

Чтобы добавить цвета к вашим линиям в зависимости от их значения, вы можете использовать биннинг и метки (как в этом ответе), чтобы создать новые столбцы с именами AAPL_color и MSFT_color, которые содержат строку цвета css (например, 'darkorange' или 'green'). Затем вы можете передать информацию из этих столбцов, используя аргумент line=dict(color=...) в каждом go.Scatter3d объекте.

import yfinance as yf
import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

stocks = ["AAPL", "MSFT"]

df_stocks = pd.DataFrame()
for stock in stocks:
    df = yf.download(stock, start = "2022-01-01", end = "2022-07-01", group_by='ticker')
    df['perct'] = df['Close'].pct_change()
    df_stocks[stock] = df['perct']

df_stocks.iloc[0] = 0
df_stocks += 1
df_stocks = df_stocks.cumprod()*100
df_stocks -= 100 

df_min = df_stocks[['AAPL','MSFT']].min().min() - 1
df_max = df_stocks[['AAPL','MSFT']].max().max() + 1

labels = ['firebrick','darkorange','peachpuff','palegoldenrod','palegreen','green']
bins = np.linspace(df_min,df_max,len(labels)+1)
df_stocks['AAPL_color'] = pd.cut(df_stocks['AAPL'], bins=bins, labels=labels).astype(str)
df_stocks['MSFT_color'] = pd.cut(df_stocks['MSFT'], bins=bins, labels=labels).astype(str)

frames = [go.Frame(
    data=[
        go.Scatter3d(
            y=df_stocks.iloc[:i].index, 
            z=df_stocks.iloc[:i].AAPL.values,
            x=['AAPL']*i,
            name='AAPL',
            mode='lines',
            line=dict(
                color=df_stocks.iloc[:i].AAPL_color.values, width=3,
            )
        ), 
        go.Scatter3d(
            y=df_stocks.iloc[:i].index, 
            z=df_stocks.iloc[:i].MSFT.values,
            x=['MSFT']*i,
            name='MSFT',
            mode='lines',
            line=dict(
                color=df_stocks.iloc[:i].MSFT_color.values, width=3,
            )
        )]
    ) 
for i in range(len(df_stocks))]

fig = go.Figure(
    data=list(frames[1]['data']),
    frames=frames,
    layout=go.Layout(
        # xaxis=dict(range=[0, 5], autorange=False),
        # yaxis=dict(range=[0, 5], autorange=False),
        # zaxis=dict(range=[0, 5], autorange=False),
        template='plotly_dark',
        legend = dict(bgcolor = 'grey'),
        updatemenus=[dict(
            type = "buttons",
            font=dict(color='black'),
            buttons=[dict(label = "Play",
                          method = "animate",
                          args=[None])])]
    ),
)

fig.show()

О, круто! сделал мой день! Я играю, чтобы сделать это быстрее, помещая линии ближе к центру и меняя галочки по оси X...

Alex 17.02.2023 20:15

@Alex рад слышать, что мой ответ был полезен! вы определенно можете внести некоторые эстетические изменения — я считаю, что частотой кадров можно управлять с помощью параметра "duration", как показано здесь

Derek O 17.02.2023 20:18

@ Дерек О. Я разделил цвета в отдельный фрейм данных и пытаюсь перебрать акции, чтобы добавить каждую с помощью go.Scatter3d. Мне нужно добавить более 10 акций (что было бы утомительно делать вручную). Где я должен разместить цикл в моем коде? Спасибо за помощь.

Alex 18.02.2023 17:38

@ Алекс, я думаю, вы можете использовать понимание списка внутри аргумента data, когда вы определяете frames. что-то вроде: frames = [go.Frame(data=[go.Scatter3d(...use col as needed...) for col in col_names]) for i in range(len(df_stocks))]

Derek O 18.02.2023 18:34

Другие вопросы по теме