Merging two plotly express figures with animation_frame into one figure with a single animation_frame

Hello,

I want to create a line chart with plotly that displays a dataframe column values (column ‘old_price’) as lines (on line for each year) and uses an animation_frame to scroll between different months for the values. I want to display another column of the same dataframe (column ‘new_price’) with markers to make it visible compared to the lines. The animation_frame should also work for the values displayed with markers and only display the values corresponding to the month selected in the scroll bar (for both ‘old_price’ and ‘new_price’).

In the attempt below, the values of the scatter plot figure (‘new_price’) that I add into the first lines figure aren’t grouped by month (all the months for 'new_price are displayed for every run_date) and the scroll bar does not work for them.


import pandas as pd
import numpy as np
import random
import plotly.express as px

# building a random dataframe in the same format of my input data as an example
price_df = pd.DataFrame()
run_dates = pd.date_range(start='2020-11-01', end='2020-12-25').tolist()
years = list(range(2015,2020))
months = list(range(1,7))
months_l = []
years_l = []

for each_year in years:
    years_l = years_l + [each_year] * len(months)
    months_l = months_l + months

years_lf = years_l * len(run_dates)
months_lf = months_l * len(run_dates)

run_dates_l = []
for each_run_date in run_dates:
    run_dates_l = run_dates_l + [each_run_date] * len(months_l)

price_df['run_dates'] = run_dates_l
price_df['years']      = years_lf
price_df['months']     = months_lf

old_price = []
new_price = []

j = 0

for i in range(len(months_lf)):
    n = random.randint(0 + j, 10 + j)
    old_price.append(n)
    n = random.randint(5 + j, 10 + j)
    new_price.append(n)
    j = j + 10

price_df['old_price']   = np.nan
price_df['new_price'] = np.nan


j = 0
for each_year in years:
    old_price = []
    val_len = len(price_df[['old_price']][price_df['years'] == each_year])
    for i in range(val_len):
        n = random.randint(0 + j, 10 + j)
        old_price.append(n)
    price_df.loc[price_df.years == each_year, 'old_price'] = old_price
    j = j + 10

j = 5
for each_month in months:
    new_price = []
    val_len = len(price_df[['new_price']][price_df['months'] == each_month])
    for i in range(val_len):
        n = random.randint(30 + j, 35 + j)
        new_price.append(n)
    price_df.loc[price_df.months == each_month, 'new_price'] = new_price
    j = j + 5

# creating the figure (I want to make a line graph displaying all the old_price values for the past run_dates for a certain month, with one line for each year; then on top of it I want to display the latest_price values for each run_dates using markers. I want to use an animation frame to change the month being displayed on the graph. When moving along the animation frame scroll bar, both the old_price values and the new_price should change to the selected month)
# Below is my best attempt
fig = px.line(price_df, x = 'run_dates', y = 'old_price', color = 'years', animation_frame = 'months')
fig2 = px.scatter(price_df, x = 'run_dates', y = 'new_price', animation_frame = 'months')
fig.add_trace(fig2.data[0])
fig.show()

#Unfortunately the new_price data isn't linked to the scroll bar and for each run_dates the prices of all months get displayed instead of just the new_price corresponding to the month selected in the scroll bar

Could you please let me know how I can make the ‘new_price’ values displayed as a scatter plot work with the existing animation_frame that’s controlling the rest of the data (‘old_price’ displayed as lines)?

Thank you very much.

2 Likes

@Emmanuelle sorry for the bother but anyway someone could help me out with this question? I really can’t find the answer anywhere…

+1 I am also facing this problem. Really appreciated if someone knows how to solve this either with plotly express or a simple way of doing this with go Figure with dictionaries.