Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object of type Period is not JSON serializable in plotly

Tags:

pandas

plotly

I am trying to plot a line chart. Below is my code

CODE :

import plotly.offline as pyo
import plotly.graph_objects as go
flag = determineFlag('2020-03-01','2020-03-30')

df_r = getDataForTrend(df,'2020-03-01','2020-03-30','d')

colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}



data = [go.Scatter(x = df_r[df_r['S2PName-Category']==category]['S2BillDate'],
                    y = df_r[df_r['S2PName-Category']==category]['totSale'],
                    mode = 'lines',
                    name = category) for category in df_r['S2PName-Category'].unique()]


layout = {'title':'Category Trend',
         'xaxis':{'title':'Time Frame'},
         'yaxis':{'title':'Total Sales Amount','tickformat' : '.2f'}}

fig = go.Figure(data=data,layout=layout)

pyo.iplot(fig)

when I run the above code I get the below error:

ERROR:

TypeError: Object of type Period is not JSON serializable

While tying to debug, I try to execute the below code

DEBUG CODE :

df_r[df_r['S2PName-Category']==category]['S2BillDate']

OP :

3     2020-03-01
11    2020-03-02
21    2020-03-03
26    2020-03-04
41    2020-03-06
42    2020-03-05
46    2020-03-07
Name: S2BillDate, dtype: period[D]

How can I fix the type error ? Is there any tweaks to this ? Any help is much appreciated! Thanks !

like image 917
Ragesh Kr Avatar asked Apr 07 '20 20:04

Ragesh Kr


People also ask

How do I fix the object of type datetime is not JSON serializable?

The Python "TypeError: Object of type datetime is not JSON serializable" occurs when we try to convert a datetime object to a JSON string. To solve the error, set the default keyword argument to str in your call to the json. dumps() method.

Is not JSON serializable?

The Python "TypeError: Object of type function is not JSON serializable" occurs when we try to serialize a function to JSON. To solve the error, make sure to call the function and serialize the object that the function returns.


1 Answers

AFAIK this is still an issue and plotly will fail in such situation. There is still an open issue at github: Support for Pandas Time spans as index col.

As proposed in the comments one of the solution is to use to_timestatmp conversion, see this.

  1. Create MWE (this is just for reproducibility since there is no data provided in the question)
import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.offline as pyo

df = pd.DataFrame({"one": np.random.random(10)}, index=pd.period_range("2020-03-01", freq="M", periods=10))
# Out:
#               one
# 2020-03  0.302359
# 2020-04  0.919923
# 2020-05  0.673808
# 2020-06  0.718974
# 2020-07  0.754675
# 2020-08  0.731673
# 2020-09  0.772382
# 2020-10  0.654555
# 2020-11  0.549314
# 2020-12  0.101696

data = [
    go.Scatter(
        x=df.index,
        y=df["one"],
    )
]
fig = go.Figure(data=data)
pyo.iplot(fig)
# -> will fail ("TypeError: Object of type Period is not JSON serializable")
  1. Use to_timestamp conversion (-> df.index.to_timestamp())
data = [
    go.Scatter(
        x=df.index.to_timestamp(), # period to datetime conversion
        y=df["one"],
    )
]
fig = go.Figure(data=data)
pyo.iplot(fig)

Or, if you do not need datetime format you can convert this to string as well:

data = [
    go.Scatter(
        x=df.index.strftime("%Y-%m"),  # You can define your own format
        y=df["one"],
    )
]
fig = go.Figure(data=data)
pyo.iplot(fig)

You can of course do this conversion right on the original dataframe (so you do not need to do it iteratively inside go.Scatter), but this is just minor stuff. There might be also a way of using custom encoder instead of the default one, but I think it's not worthy of trying and afaik there is no better solution than using one of possible conversion from Period to datetime or string.

like image 183
Nerxis Avatar answered Sep 24 '22 07:09

Nerxis