Replies: 6 comments 5 replies
-
Could you format your code properly? |
Beta Was this translation helpful? Give feedback.
-
This is what I found. That sample code is incomplete, there is no I test it with a different code. The issue is in The parameter Could there be an issue in def create_fig(data):
fig = px.pie(
data,
values="Count",
names="Status",
hole=0.8,
color="Status",
color_discrete_map={"Success": "#D7BB0B", "Failed": "#F2F2F2"},
height=70,
)
...
fig.write_html("fig.html", include_plotlyjs="cdn")
fig_html = open("fig.html", "r", encoding="utf-8").read()
return html.div(utils.html_to_vdom(fig_html)) # <========== |
Beta Was this translation helpful? Give feedback.
-
I also tried rendering the image, by saving the fig to 'png'. It also does not work. But if I randomize the image filename, it will render. So this is my current workaround. Sample import pandas as pd
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
def read_data(filter: str) -> list[dict]:
data = [
{"Status": "Success", "Count": 200, "Quality": "A"},
{"Status": "Failed", "Count": 50, "Quality": "S"},
{"Status": "Success", "Count": 50, "Quality": "C"},
{"Status": "Failed", "Count": 17, "Quality": "A"},
{"Status": "Success", "Count": 95, "Quality": "C"},
{"Status": "Failed", "Count": 85, "Quality": "A"},
{"Status": "Success", "Count": 4, "Quality": "S"}
]
df = pd.DataFrame(data)
df = df.loc[df['Quality'] == filter]
return df.to_dict('records') def create_fig(chart_data: list[dict]):
...
imgfn = f'{str(uuid.uuid4())[:12]}_fig.png'
fig.write_image(f"./static/{imgfn}")
return html.img({'src': f'/static/{imgfn}', 'style': {'width': '50%'}}) |
Beta Was this translation helpful? Give feedback.
-
It may not be necessary to save the image to disk. This also works. import base64
img_bytes = fig.to_image(format="png")
encoded = base64.b64encode(img_bytes).decode("utf-8")
return html.img({'src': f'data:image/png;base64, {encoded}'}) |
Beta Was this translation helpful? Give feedback.
-
Got it, we actually need a button to plot. Users will select "A" or "B" or "S". After the selection, we let users to press the button to plot data based on their filter. The interaction component@component
def interactions_layout():
data_filter, set_data_filter = hooks.use_state("C")
plotly_data, set_plotly_data = hooks.use_state(read_data(data_filter))
def plot_data(event):
res = read_data(data_filter)
# print(f'current data after filter: {res}')
set_plotly_data(res)
# html.div(create_fig(plotly_data)),
def handle_event(event):
set_data_filter(event["target"]["value"])
return html.div(
Select(handle_event, data_filter),
html.div(
html.button(
{
"style": {"margin-top": "10px"},
"on_click": plot_data
}, "Plot data"
),
html.div(create_fig(plotly_data)),
)
) Separate component for select@component
def Select(handle_event, data_filter):
return html.div(
html.select(
{
'style': {
'width': '100px'
},
"value": data_filter,
"on_change": handle_event
},
html.option({"value": "A"}, "A"),
html.option({"value": "C"}, "C"),
html.option({"value": "S"}, "S")
)
) |
Beta Was this translation helpful? Give feedback.
-
This is the full reproducible sample code. See some comments in It is better if the plotly html will work as the users can interact on the rendered plot. Currently only the image worked. I test it on my windows 10 PC. from io import StringIO
import base64
from reactpy import component, html, utils, hooks
from reactpy.backend.fastapi import configure, Options
from fastapi import FastAPI
import plotly
import plotly.express as px
import pandas as pd
PLOTLY_JS = {
'src': 'https://cdn.plot.ly/plotly-latest.min.js',
'charset': 'utf-8'
}
DATA = [
{"Status": "Success", "Count": 200, "Quality": "A"},
{"Status": "Failed", "Count": 50, "Quality": "S"},
{"Status": "Success", "Count": 50, "Quality": "C"},
{"Status": "Failed", "Count": 17, "Quality": "A"},
{"Status": "Success", "Count": 95, "Quality": "C"},
{"Status": "Failed", "Count": 85, "Quality": "A"},
{"Status": "Success", "Count": 4, "Quality": "S"}
]
def read_data(filter: str) -> list[dict]:
df = pd.DataFrame(DATA)
df = df.loc[df['Quality'] == filter]
return df.to_dict('records')
def get_fig(chart_data: list[dict]) -> plotly.graph_objs._figure.Figure:
df = pd.DataFrame(chart_data)
fig = px.pie(
df,
values="Count",
names="Status",
hole=0.8,
color="Status",
color_discrete_map={"Success": "#D7BB0B", "Failed": "#F2F2F2"},
height=300,
width=400,
title=f"Plot for filter {chart_data[0]['Quality']}"
)
return fig
def create_fig(chart_data: list[dict]):
fig = get_fig(chart_data)
# (1) fig->html_buffer->vdom does not work when data is updated.
# buffer = StringIO()
# fig.write_html(buffer, include_plotlyjs='cdn')
# fig_html = buffer.getvalue()
# return html.div(utils.html_to_vdom(fig_html))
# (2) fig->html_file->vdom does not work when data is updated.
# htmlfn = 'fig.html'
# fig.write_html(htmlfn, include_plotlyjs="cdn")
# fig_html = open(htmlfn, "r", encoding='utf-8').read()
# return html.div(utils.html_to_vdom(fig_html))
# (3) fig->bytes->img does work even if data is updated.
# Disadvantage: Users cannot interact with the image.
img_bytes = fig.to_image(format="png")
encoded = base64.b64encode(img_bytes).decode("utf-8")
return html.img({'src': f'data:image/png;base64, {encoded}'})
@component
def Select(handle_event, data_filter):
return html.div(
html.select(
{
'style': {
'width': '100px'
},
"value": data_filter,
"on_change": handle_event
},
html.option({"value": "A"}, "A"),
html.option({"value": "C"}, "C"),
html.option({"value": "S"}, "S")
)
)
@component
def PlotButton(plot_data):
return html.div(
html.button(
{
"style": {"margin-top": "10px", "width": "100px"},
"on_click": plot_data
},
"Plot data"
)
)
@component
def interactions_layout():
data_filter, set_data_filter = hooks.use_state("C")
plotly_data, set_plotly_data = hooks.use_state(read_data(data_filter))
def plot_data(event):
set_plotly_data(read_data(data_filter))
def handle_event(event):
set_data_filter(event["target"]["value"])
return html.div(
Select(handle_event, data_filter),
PlotButton(plot_data),
html.div(create_fig(plotly_data))
)
@component
def Dashboard():
return interactions_layout()
app = FastAPI()
configure(
app,
Dashboard,
Options(
head=html.head(
html.script(PLOTLY_JS)
)
)
) |
Beta Was this translation helpful? Give feedback.
-
Hi,
I have created a plotly chart on my web page with some filters that filter the data depending on what a user selects.
Basic calculations are filtering successfully however the plotly graph remains static. Below is a snippet of my code:
Beta Was this translation helpful? Give feedback.
All reactions