A. Plotly in Python
ReactPy is a python library used to create user interfaces for web application. Plotly is a library for data visualization. It can generate bar, line charts and many others.Let us create a practical example of data visualization using Plotly in an application developed from reactpy. Our data is from a csv file with expenses records. You may download the sample expenses.csv from my google drive. Place this file in the same folder where your module or chart.py is located.
Contents of expenses.csv
Date Amount Category 0 2023-08-01 80.0 Utilities 1 2023-08-01 20.0 Food 2 2023-08-01 6.0 Transportation 3 2023-08-01 5.0 Personals 4 2023-08-01 15.0 Supplies 5 2023-08-02 12.0 Food 6 2023-08-02 8.0 Transportation 7 2023-08-03 18.0 Food 8 2023-08-03 8.0 Transportation 9 2023-08-04 15.0 Food 10 2023-08-04 8.0 Transportation 11 2023-08-04 25.0 Recreation 12 2023-08-04 10.0 Housing 13 2023-08-05 50.0 Supplies 14 2023-08-05 30.0 Food 15 2023-08-05 12.0 Transportation 16 2023-08-05 130.0 Clothing
Our dataframe has 3 columns, Date, Amount and Category. We will create a bar chart showing the sum in each category.
Here is the code to sum the Category using pandas' groupby.
DATA_FILENAME = 'expenses.csv' df = pd.read_csv(DATA_FILENAME) # Group the Category and sum it. df_grp = df.groupby(['Category'])['Amount'].sum().reset_index() print(df_grp)
This is the grouped dataframe output.
Category Amount 0 Clothing 130.0 1 Food 95.0 2 Housing 10.0 3 Personals 5.0 4 Recreation 25.0 5 Supplies 65.0 6 Transportation 42.0 7 Utilities 80.0
B. Bar chart in Plotly Python
This is the bar chart written in Python.
# Create a figure using the grouped dataframe. fig = px.bar(df_grp, x='Amount', y='Category', orientation='h', width=600, height=400, text_auto=True, title='Bar Chart') fig.show()
Now the question is how can we show the chart in a web application created by ReactPy?
C. Expenses Bar Chart in ReactPy
Plotly has a method to convert the figure into an html, while ReactPy has a way to convert an html to its VDOM (Virtual Document Object Model) representation. We can combine those to generate an applicaton in ReactPy that shows a chart.
Step 1: Convert the plotly figure to html
No, we don't output an html file, instead we hold the figure in memory as an html object.
# Create an html object in memory from fig. buffer = StringIO() fig.write_html(buffer, include_plotlyjs='cdn') fig_html = buffer.getvalue()
Step 2: Convert the figure html to ReactPy VDOM
utils.html_to_vdom(fig_html)
D. BarChart component
@component def BarChart(): """Creates a plotly bar chart.""" # Read csv file and convert to dataframe. df = pd.read_csv(DATA_FILENAME) # Group similar category and sum it. df_grp = df.groupby(['Category'])['Amount'].sum().reset_index() # Create a figure using the grouped dataframe. fig = px.bar( df_grp, x='Amount', y='Category', orientation='h', width=600, height=400, text_auto=True, title='Bar Chart' ) # Create an html object in memory from fig. buffer = StringIO() fig.write_html(buffer, include_plotlyjs='cdn') fig_html = buffer.getvalue() return html.div( html.h2('Plotly Bar Chart in ReactPy'), utils.html_to_vdom(fig_html) )
E. Full code
chart.py"""Renders plotly chart in ReactPy""" from io import StringIO from reactpy import component, html, utils from reactpy.backend.fastapi import configure, Options from fastapi import FastAPI import plotly.express as px import pandas as pd DATA_FILENAME = 'expenses.csv' PAGE_TITLE = 'ReactPy-PlotlyChart' PLOTLY_JS = { 'src': 'https://cdn.plot.ly/plotly-latest.min.js', 'charset': 'utf-8' } @component def BarChart(): """Creates a plotly bar chart.""" # Read csv file and convert to dataframe. df = pd.read_csv(DATA_FILENAME) # Group similar category and sum it. df_grp = df.groupby(['Category'])['Amount'].sum().reset_index() # Create a figure using the grouped dataframe. fig = px.bar( df_grp, x='Amount', y='Category', orientation='h', width=600, height=400, text_auto=True, title='Bar Chart' ) # Create an html object in memory from fig. buffer = StringIO() fig.write_html(buffer, include_plotlyjs='cdn') fig_html = buffer.getvalue() return html.div( html.h2('Plotly Chart in ReactPy'), utils.html_to_vdom(fig_html) ) app = FastAPI() configure( app, BarChart, Options( head=html.head( html.script(PLOTLY_JS), html.title(PAGE_TITLE) ) ) )
This is the page output.
F. Required modules
requirements.txtreactpy[fastapi] plotly pandas uvicorn[standard]
Have a look on how to install reactpy.
G. Command line to run the chart.py
uvicorn chart:app
H. Line Chart Component
This component is similar to BarChart
but our x-axis is Date
and y-axis is Amount
. Also we will group the amount by Date
so that we can see the daily trend of the expenses.
# Group similar category and sum it. df_grp = df.groupby(['Date'])['Amount'].sum().reset_index()
This is the full line chart component code.
@component def LineChart(): """Creates a plotly line chart.""" # Read csv file and convert to dataframe. df = pd.read_csv(DATA_FILENAME) # Group similar category and sum it. df_grp = df.groupby(['Date'])['Amount'].sum().reset_index() # Create a figure using the grouped dataframe. fig = px.line( df_grp, x='Date', y='Amount', orientation='h', width=600, height=400, title='Line Chart' ) # Create an html object in memory from fig. buffer = StringIO() fig.write_html(buffer, include_plotlyjs='cdn') fig_html = buffer.getvalue() return html.div( html.h2('Plotly Line Chart in ReactPy'), utils.html_to_vdom(fig_html) )
If you use this component, it would look like this.
The change is this.
app = FastAPI() configure( app, LineChart, # this one Options( head=html.head( html.script(PLOTLY_JS), html.title(PAGE_TITLE) ) ) )
I. Combine the two components
Instead of a single chart, we can place the two charts in the page.This is our root component
@component def ChartCombo(): return html.div( BarChart(), LineChart() )
This is the full code.
mychart.py"""Renders plotly chart in ReactPy""" from io import StringIO from reactpy import component, html, utils from reactpy.backend.fastapi import configure, Options from fastapi import FastAPI import plotly.express as px import pandas as pd DATA_FILENAME = 'expenses.csv' PAGE_TITLE = 'ReactPy-PlotlyChart' PLOTLY_JS = { 'src': 'https://cdn.plot.ly/plotly-latest.min.js', 'charset': 'utf-8' } @component def BarChart(): """Creates a plotly bar chart.""" # Read csv file and convert to dataframe. df = pd.read_csv(DATA_FILENAME) # Group similar category and sum it. df_grp = df.groupby(['Category'])['Amount'].sum().reset_index() # Create a figure using the grouped dataframe. fig = px.bar( df_grp, x='Amount', y='Category', orientation='h', width=600, height=400, text_auto=True, title='Bar Chart' ) # Create an html object in memory from fig. buffer = StringIO() fig.write_html(buffer, include_plotlyjs='cdn') fig_html = buffer.getvalue() return html.div( html.h2('Plotly Bar Chart in ReactPy'), utils.html_to_vdom(fig_html) ) @component def LineChart(): """Creates a plotly line chart.""" # Read csv file and convert to dataframe. df = pd.read_csv(DATA_FILENAME) # Group similar category and sum it. df_grp = df.groupby(['Date'])['Amount'].sum().reset_index() # Create a figure using the grouped dataframe. fig = px.line( df_grp, x='Date', y='Amount', orientation='h', width=600, height=400, title='Line Chart' ) # Create an html object in memory from fig. buffer = StringIO() fig.write_html(buffer, include_plotlyjs='cdn') fig_html = buffer.getvalue() return html.div( html.h2('Plotly Line Chart in ReactPy'), utils.html_to_vdom(fig_html) ) @component def ChartCombo(): return html.div( BarChart(), LineChart() ) app = FastAPI() configure( app, ChartCombo, Options( head=html.head( html.script(PLOTLY_JS), html.title(PAGE_TITLE) ) ) )
Run the app with the following command line.
uvicorn mychart:app
The rendered page.
J. Pie chart component
The pie chart shows figures in percentages. Useful to see how the categories differ by percent.
@component def PieChart(): """Creates a plotly pie chart.""" # Read csv file and convert to dataframe. df = pd.read_csv(DATA_FILENAME) # Group similar category and sum it. df_grp = df.groupby(['Category'])['Amount'].sum().reset_index() # Create a figure using the grouped dataframe. fig = px.pie(df_grp, values='Amount', names='Category', width=500, height=500, title='Pie Chart') # Create an html object in memory from fig. buffer = StringIO() fig.write_html(buffer, include_plotlyjs='cdn') fig_html = buffer.getvalue() return html.div( html.h2('Plotly Pie Chart in ReactPy'), utils.html_to_vdom(fig_html) )
K. Scatter chart component
Scatter chart tells us the relationship between two variables. We will create a scatter chart showing the relationships between 'Food' and 'Transportation' costs. Do some data preprocessing such as collecting all the daily food and transportation costs and build a dataframe with 'Food' and 'Transportation' columns.
DATA_FILENAME = 'expenses.csv' # Read csv file and convert to dataframe. df = pd.read_csv(DATA_FILENAME) # Create a new dataframe showing Food and Transportation column. food = df.loc[df.Category == 'Food'] transportation = df.loc[df.Category == 'Transportation'] new_df = pd.DataFrame( {'Food': food['Amount'].to_list(), 'Transportation': transportation['Amount'].to_list()} ) print(new_df)
Output
Food Transportation 0 20.0 6.0 1 12.0 8.0 2 18.0 8.0 3 15.0 8.0 4 30.0 12.0
So we have a dataframe with two columns. Each row has column values, this is enough to visualize what those figures are. Do the food costs increases with transportation or the otherway around or no relationships at all.
This is our scatter plot.
Full scatter component code
@component def Scatter(): """Creates a plotly scatter chart.""" # Read csv file and convert to dataframe. df = pd.read_csv(DATA_FILENAME) # Create a new dataframe showing Food and Transportation column. food = df.loc[df.Category == 'Food'] transportation = df.loc[df.Category == 'Transportation'] new_df = pd.DataFrame( {'Food': food['Amount'].to_list(), 'Transportation': transportation['Amount'].to_list()} ) # Create figure. fig = px.scatter( new_df, x='Food', y='Transportation', width=600, height=400, title='Scatter Chart' ) # Create an html object in memory from fig. buffer = StringIO() fig.write_html(buffer, include_plotlyjs='cdn') fig_html = buffer.getvalue() return html.div( html.h2('Plotly Chart in ReactPy'), utils.html_to_vdom(fig_html) )
L. Summary
Charts built from ploty can be shown in reactpy app. Plotly-created figure is converted to html text and shown in ReactPy app by transforming the html to ReactPy VDOM.