This tutorial presents the newest dashboard app to visualize Ethereum data from Adam’s CharmingData channel:
Adam is the lead author of our book Plotly Dash — you can check it out here:
But first things first: What is Plotly Dash anyway? π Dash is a Python framework for building analytical web applications, and Plotly is a graphing library for making interactive plots.
As you read through this tutorial, feel free to watch Adam’s excellent video explanation:
Let’s dive into the code from the GitHub, I’ll explain it in a minute. Here’s the high-level summary:
π‘ TLDR: This code is a Dash web application that displays live gas prices on the Ethereum blockchain, a line chart showing Ethereum’s value over time, and a line chart showing the number of active Ethereum addresses over time.
from dash import Dash, html, dcc, Input, Output, callback # pip install dash import dash_bootstrap_components as dbc # pip install dash-bootstrap-components import plotly.express as px import pandas as pd # pip install pandas from urllib.request import Request, urlopen from dotenv import dotenv_values # pip install python-dotenv import json # get eth-to-usd dataset df_eth_usd = pd.read_csv("https://raw.githubusercontent.com/Coding-with-Adam/Dash-by-Plotly/master/Analytic_Web_Apps/Blockchain-minimal/Gemini_ETHUSD_d.csv") df_eth_usd['date'] = pd.to_datetime(df_eth_usd['date']) # get eth-addresses dataset df_eth_addr = pd.read_csv("https://raw.githubusercontent.com/Coding-with-Adam/Dash-by-Plotly/master/Analytic_Web_Apps/Blockchain-minimal/DailyActiveEthAddress.csv") df_eth_addr['date'] = pd.to_datetime(df_eth_addr['date']) # set up beaconchain api key for data on gas prices config = dotenv_values(".env") api_key = config['API_KEY'] # your .env file should have this line: API_KEY = "your-beaconchain-api-key" # function to build one card for each gas price category def make_card(key, get_data): return dbc.Card( [ dbc.CardHeader(html.H2(key)), dbc.CardBody([ html.H3( f"{int(get_data[key] / 1000000000)} GWei", id=key), ]) ], className="text-center shadow") # display app components on page app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP]) app.layout = dbc.Container([ html.H1("Live Gas Prices", style={'textAlign': 'center'}), dbc.Row(children=[], id='gas-data-display',className="my-4"), dbc.Row([ dbc.Col([ html.H3("Eth Value"), dcc.Dropdown(options=df_eth_usd.columns[3:], value='open', clearable=False, id='col_price'), dcc.Graph(figure={}, id='eth_usd_graph') ], width=6), dbc.Col([ html.H3("Active Ethereum Addresses"), dcc.Dropdown(options=df_eth_addr.columns[1:], value='Unique Address Total Count', clearable=False, id='col_addr'), dcc.Graph(figure={}, id='eth_addr_graph') ], width=6) ]), dcc.Interval(id='update_trigger', interval=1000*4) # trigger every 4 seconds ]) # build the graphs based on dropdown value selected @callback( Output(component_id='eth_usd_graph', component_property='figure'), Output('eth_addr_graph', component_property='figure'), Input('col_price', component_property='value'), Input('col_addr', component_property='value') ) def udpate_graph(col_p_selected, col_a_selected): price_fig = px.line(data_frame=df_eth_usd, x='date', y=col_p_selected) addr_fig = px.line(data_frame=df_eth_addr, x='date', y=col_a_selected) return price_fig, addr_fig # interval component triggers the callback to pull the current gas prices @callback( Output('gas-data-display','children'), Input('update_trigger','n_intervals') ) def udpate_gas_price(_): gas_price = {"code":200,"data":{"rapid":31701870016,"fast":24753659720,"standard":24753659720,"slow":24753659720}} # req = Request( # url=f'https://beaconcha.in/api/v1/execution/gasnow?apikey={api_key}', # headers={'User-Agent': 'Mozilla/5.0'} # ) # web_byte = urlopen(req).read() # gas_price_string = web_byte.decode('utf-8') # gas_price = json.loads(gas_price_string) # convert string to dict # gas_price["data"].pop("timestamp") # gas_price["data"].pop("priceUSD") # print(gas_price) gas_cards = [dbc.Col(make_card(y, gas_price["data"])) for y in gas_price["data"]] return gas_cards if __name__ == '__main__': app.run(debug=True)
Wow, just a few lines of code to build a beautiful dashboard app in the blockchain space! π€―π§βπ»
Here’s a step-by-step explanation:
- Import necessary libraries.
- Dash is a productive Python framework for building web applications.
dash_bootstrap_components
is a library for adding Bootstrap components to your Dash apps.plotly.express
is a simple syntax for complex charts.pandas
is a data manipulation and analysis library.urllib.request
is used to open URLs.dotenv
is used to pull the API key from a local.env
file.json
is used to parse JSON formatted data.
- Get and process the
eth-to-usd
dataset from a GitHub repository, changing the'date'
column to adatetime
format. The same is done for theeth-addresses
dataset. - Load the API key for beaconchain from a
.env
file, which is used to fetch Ethereum’s gas prices. - Define a function
make_card(key, get_data)
. This function will build a Bootstrap card for each gas price category. - Set up the Dash application and define the layout of the app.
- The layout is a Bootstrap container that includes a heading, rows of Bootstrap cards, and two columns each containing a dropdown and a graph. The dropdowns are populated with column headers from the two datasets.
- The
dcc.Interval
component is used to trigger an update function every 4 seconds.
- Define a callback function
udpate_graph(col_p_selected, col_a_selected)
. This function takes as input the selected values from the two dropdowns, uses those to select columns from the two dataframes, and returns line charts of those columns. - Define another callback function
udpate_gas_price(_)
. This function is triggered every time theInterval
component completes a cycle (every 4 seconds). This function fetches the current gas prices, builds Bootstrap cards with these prices, and returns these cards as a list of columns to be displayed in the'gas-data-display'
row. The actual API request is commented out, so the function currently uses hardcoded data. - Finally, if the script is run directly (as opposed to being imported as a module), it starts the Dash server with debug mode on. This mode provides detailed error messages, and the server will automatically reload when it detects changes in the source code.
Please note that the code currently uses hardcoded data for gas prices. The commented-out section shows how you could fetch live data from an API using an API key stored in a .env
file. To use this live data, you would need to uncomment the relevant section and provide your own API key.
π Recommended: Python Plotly Dash Cheat Sheet
If you’re interested in learning more about how to create beautiful dashboard applications in Python, check out our new book Python Dash.
Youβve seen dashboards before; think election result visualizations you can update in real-time, or population maps you can filter by demographic.
With the Python Dash library, youβll create analytic dashboards that present data in effective, usable, elegant ways in just a few lines of code.
Get the book on NoStarch or Amazon!