Doubt: Help with Looping through datetime for plotting time series bar chart race

This is essentially the data I am working with.

This is the dataset:
datasets_549966_1402864_complete.csv (280.1 KB)


My Code:

import pandas as pd
import plotly.graph_objects as go
pop1 = pd.read_csv('corona.csv', encoding = 'Latin-1')
pop1.head()

pop2 = pop1[pop1['Date']=='2020-08-06'].sort_values(by = 'Total Confirmed cases', ascending = False)

pop3 = pop2['Name of State / UT'].head(10)
list1 = pop3.values.tolist()

pop4 = pop1.loc[pop1['Name of State / UT'].isin(list1)].sort_values(['Date','Total Confirmed cases'],ascending = [True,False])

pop4['Date']= pd.to_datetime(pop4['Date'])


'''Creation of a sequence of frames. 
Parameters:
    df (DataFrame): Pandas data frame containing the categorical variable ['Name'],
    the count ['Number'], the year ['Year'], and the color['Color'] (separated columns).
    title (string): Title of each frame.
    Returns:
    list_of_frames (list): List of frames. Each frame contains a bar plot of a year'''

def frames_animation(df, title):
    list_of_frames = []
    initial_year = pd.todatetime(df['Date'].min())
    final_year = pd.todatetime(df['Date'].max())
    
    for year in range(initial_year, final_year):
        fdata = df[df['Date'] == year]
        list_of_frames.append(go.Frame(data=[go.Bar(x=fdata['Name of State / UT'], y=fdata['Total Confirmed cases'],
                                                        hoverinfo='none',
                                                        textposition='outside', texttemplate='%{x}<br>%{y}',
                                                        cliponaxis=False)],
                                           layout=go.Layout(font={'size': 14},
                                                            plot_bgcolor = '#FFFFFF',
                                                            xaxis={'showline': False, 'visible': False},
                                                            yaxis={'showline': False, 'visible': False},
                                                            bargap=1,
                                                            title=title + str(year))))
    return list_of_frames

'''Creation of the bar chart race figure.
    Parameters:
    df (DataFrame): Pandas data frame containing the categorical variable ['Name'],
    the count ['Number'], the year ['Year'], and the color ['Color'] (separated columns).
    title (string): Title of the initial bar plot.
    list_of_frames (list): List of frames. Each frame contains a bar plot of a year.
    Returns:
    fig (figure instance): Bar chart race '''


def bar_race_plot (df, title, list_of_frames):
    initial_year = df['Date'].min()
    initial_names = df[df['Date'] == initial_year]['Name of State / UT']
    initial_numbers = df[df['Date'] == initial_year]['Total Confirmed cases']
    range_max = df['Total Confirmed cases'].max()
    
    fig = go.Figure(
        data=[go.Bar(x=initial_names, y=initial_numbers,
                       hoverinfo='none',
                       textposition='outside', texttemplate='%{x}<br>%{y}',
                       cliponaxis=False)],
        layout=go.Layout(font={'size': 14}, plot_bgcolor = '#FFFFFF',
                         xaxis={'showline': False, 'visible': False},
                         yaxis={'showline': False, 'visible': False, 'range': (0, range_max)},
                         bargap=1, title=title + str(initial_year),
                         updatemenus=[dict(type="buttons",
                                           buttons=[dict(label="Play",
                                                         method="animate",
                                                         args=[None,{"frame": {"duration": 2000, "redraw": True}, "fromcurrent": True}]),
                                                    dict(label="Stop",
                                                         method="animate",
                                                         args=[[None],{"frame": {"duration": 0, "redraw": False}, "mode": "immediate","transition": {"duration": 0}}])])]),frames=list(list_of_frames))
    
    return fig


# animated bar chart for my case
title = 'Total Corona virus cases on '
list_of_frames = frames_animation(pop4, title)
fig = bar_race_plot(pop4, title, list_of_frames)
fig.show()

What I expected to happen:
This is supposed to give me a vertical bar race chart with dates and specific states

What actually happened:
I am getting an error which reads

TypeError                                 Traceback (most recent call last)
<ipython-input-15-282b6a8a7153> in <module>
      1 # animated bar chart of baby names - girls
      2 title = 'Total Corona virus cases on '
----> 3 list_of_frames = frames_animation(pop4, title)
      4 fig = bar_race_plot(pop4, title, list_of_frames)
      5 fig.show()

<ipython-input-13-9c2620914555> in frames_animation(df, title)
      4     final_year = df['Date'].max()
      5 
----> 6     for year in range(initial_year, final_year):
      7         fdata = df[df['Date'] == year]
      8         list_of_frames.append(go.Frame(data=[go.Bar(x=fdata['Name of State / UT'], y=fdata['Total Confirmed cases'],

TypeError: 'Timestamp' object cannot be interpreted as an integer

An alternative that I tried was

from datetime import timedelta, date

def daterange(start_date, end_date):
    for n in range(int((end_date - start_date).days)):
        yield start_date + timedelta(n)
        
def frames_animation(df, title):
    list_of_frames = []
    initial_year = df['Date'].min()
    final_year = df['Date'].max()
    
    for year in daterange(initial_year, final_year):
        fdata = df[df['Date'] == year]
        list_of_frames.append(go.Frame(data=[go.Bar(x=fdata['Name of State / UT'], y=fdata['Total Confirmed cases'],
                                                        hoverinfo='none',
                                                        textposition='outside', texttemplate='%{x}<br>%{y}',
                                                        cliponaxis=False)],
                                           layout=go.Layout(font={'size': 14},
                                                            plot_bgcolor = '#FFFFFF',
                                                            xaxis={'showline': False, 'visible': False},
                                                            yaxis={'showline': False, 'visible': False},
                                                            bargap=1,
                                                            title=title + str(year))))
    return list_of_frames

This, in turn, gave me a plot which was empty :frowning:

It would be great to know where I am going wrong fundamentally. I am having a tough time wrapping my head around which part of this is causing the error.

Would be great to have some help with this!

Apologies if the structure of the question is too confusing. :’(

Thanks!

1 Like

hi @swar.joshi

Please attach few sample records as well, along with/ instead of a screen shot. It’s difficult to understand if say numeric columns are numeric columns or they might be stored as object data-type or any other necessary information we might need to reproduce the error at our end.

Create a dummy dataframe in separate code block, with these same rows you have selected for the screen-shot, or extract a sample “.csv” file for the community to test your code and help work on it together.

Thanks.

1 Like

Hi @Rucha,

Sorry about that! I have updated and added the dataset ‘.csv’ file in my post with the new edit!

Thanks a ton!

2 Likes

hi @swar.joshi

Have you been able to debug this? I did few experiments and I could get a single bar (an initial one I guess) with my experiments.

I haven’t worked really with animations before. In my project I have yet only worked with sliders. I will to try to work on this again, but for now stuck with my own backlog :grimacing:

In case you have achieved a solution for this. Great! just me let me know that it’s a done deal for you. I will experiment in my own time then :wink:

1 Like

Hi @Rucha,

I have not been able to debug it yet. I gave it a few more days of my time and have posted this but haven’t gotten to a solution or a better way to do it yet.

So for the time being, I am focussing on the ongoing courses here on DQ. I will eventually circle back to this one and see if I am able to do it with my then new-found knowledge haha!

Thanks a lot for the attempt though!

1 Like