I am using plotly express
to create different graphs. I am trying to convert graphs
into json
format to save in json
file. While doing so I am getting error using different ways as below:
Way-1 code gives error as below
Error-2 Object of type ndarray is not JSON serializable
Way-2 code gives error as below
Error-2 Object of type Figure is not JSON serializable
Below is MWE:
import json
import dash_bootstrap_components as dbc
from dash import dcc
from dash_bootstrap_templates import load_figure_template
import plotly.express as px
import plotly.io as pio
import pandas as pd
def generate_pie_charts(df, template) -> list[dict[str, Any]]:
pie_charts = list()
for field in df.columns.tolist():
value_count_df = df[field].value_counts().reset_index()
cols = value_count_df.columns.tolist()
name: str = cols[0]
value: str = cols[1]
try:
# Way-1
# figure = px.pie(
# data_frame=value_count_df,
# values=value,
# names=name,
# title=f"Pie chart of {field}",
# template=template,
# ).to_plotly_json()
# pie_chart = dcc.Graph(figure=figure).to_plotly_json()
# Way-2
figure = px.pie(
data_frame=value_count_df,
values=value,
names=name,
title=f"Pie chart of {field}",
template=template,
)
figure = pio.to_json(figure)
# figure = pio.to_json(figure).encode()
pie_chart = dcc.Graph(figure=pio.from_json(figure)).to_plotly_json()
# pie_chart = dcc.Graph(figure=pio.from_json(figure.decode())).to_plotly_json()
pie_charts.append(pie_chart)
except Exception as e:
print(f"Error-1 {e}")
print(f"Length {len(pie_charts)}")
return pie_charts
def perform_exploratory_data_analysis():
rows = list()
template = "darkly"
load_figure_template(template)
info = {
"A": [
"a", "a", "b", "b", "c", "a", "a", "b", "b", "c", "a", "a", "b", "b", "c",
],
"B": [
"c", "c", "c", "c", "c", "a", "a", "b", "b", "c", "a", "a", "b", "b", "c",
],
}
df = pd.DataFrame(info)
try:
row = dbc.Badge(
"For Pie Charts", color="info", className="ms-1"
).to_plotly_json()
rows.append(row)
row = generate_pie_charts(df, template)
rows.append(row)
data = {"contents": rows}
status = False
msg = "Error creating EDA graphs."
file = "eda.json"
with open(file, "w") as json_file:
json.dump(data, json_file)
msg = "EDA graphs created."
status = True
except Exception as e:
print(f"Error-2 {e}")
result = (status, msg)
return result
perform_exploratory_data_analysis()
What I am missing?
You were close with way-2, you need to :
Convert the figure (go.Figure
) to a JSON string using pio.to_json()
, so that ndarray and other python types used in the figure's data are properly converted into their javascript equivalent.
Deserialize the JSON string using json.loads()
in order to get the figure as a standard JSON dict and prevent double encoding with future call to json.dump()
(nb. pio.from_json()
would return a go.Figure
which json.dump()
doesn't know how to serialize).
The relevant part of the code :
# ...
figure = px.pie(
data_frame=value_count_df,
values=value,
names=name,
title=f"Pie chart of {field}",
template=template,
)
# serializable figure dict
fig_dict = json.loads(figure.to_json())
pie_chart = dcc.Graph(figure=fig_dict).to_plotly_json()
# ...