<jupyter_start><jupyter_text>Notebook 5: Creating your first dashboard with Plotly and Dash The objectives of this notebook are the following:- Understand dashboards- Creating your first dashboard Here you have a link where all the information about Dash is available: https://dash.plotly.com/. Please refer to this link if you want any additional information. Dash is basically a python framework for the creation of web applications.  Part 0: Installation and setup Let's first import dash and the libraries that we will use. Make sure that you have them downloaded and installed in the right environment!These commands should help you install them in case you haven't installed them yet:```conda install -c conda-forge dashconda install -c conda-forge jupyter-dashconda install -c conda-forge dash-core-componentsconda install -c conda-forge dash-html-componentsconda install -c conda-forge dash-tableconda install -c conda-forge dash-bootstrap-components``` Once you have installed all the above, you should be able to import the following:<jupyter_code>import dash
from dash import dcc
from dash import html
from dash import dash_table
import dash_bootstrap_components as dbc
from jupyter_dash import JupyterDash<jupyter_output><empty_output><jupyter_text>Part I: Creating our first Dashboard with Dash, python and Plotly Great! If you run the above cell without running into errors, then you have all the required libraries installed. Now let's create our first simple Dashboard<jupyter_code>app = JupyterDash('Creating our first Dash!', external_stylesheets=[dbc.themes.BOOTSTRAP])<jupyter_output><empty_output><jupyter_text>We are going to use the `html` module from `dash`, which is a bridge between the commonly used and known html programming language and dash.We will use only simple features to arrange the elements on the page. We wil create simple elements, using a python dictionary containing all the parameters (data -> "x", "y", "type", "name").<jupyter_code>app.layout = html.Div(children=[
  html.H1(children='Creating our first Dashboard with python and plotly'),
  dcc.Graph(id='example',
    figure={
      'data': [
        {'x': [1, 2], 
         'y': [1, 5],
         'type': 'line',
         'name': '<NAME>'},
        {'x': [1, 2], 
         'y': [3, 2],
         'type': 'bar',
         'name': '<NAME>'},
        ],
      'layout': {
      'title': 'Creating our first Dash!'
        }
      })
  ])
app.run_server(mode='inline', host = '127.0.0.1', port=8051, debug=True)<jupyter_output><empty_output><jupyter_text>Great! Now we have our first Dash! We could also run this through another server and see it on another port. Let's try it:<jupyter_code>app.run_server(mode='external', host = '127.0.0.1', port=8051, debug=True)<jupyter_output>Dash app running on http://127.0.0.1:8051/<jupyter_text>Nice! That was very simple. Now that we know the most basic way of making a dashboard, it's time to dive into Dashboards, and try to understand what it is used for. Dashboards and multi-chart displays that are used for monitoring and analysis. One way to define Dashboard is as follows:**A dashboard is a visual display of the most important information needed to achieve one or more objectives; consolidated and arranged on a single screen so the information can be monitored at a glance.**[Source](https://www.perceptualedge.com/articles/visual_business_intelligence/dboard_confusion_revisited.pdf) So, dashboards help us create a single screen that can give us information to monitor a process, or to analyze data. One important thing to remark from this same source is that:**“The greatest clarification that is needed today is a distinction between dashboards, which are used for monitoring what’s going on, and displays that combine several charts on a screen for the purpose of analysis.”** Thus, we need to remark the importance of distincting between a monitoring tool, and a display of faceted analytical display. Let's develop a little further what faceted analytical display is:**A “faceted analytical display” is a set of charts (primarily graphs and tables) that simultaneously reside on a single screen, each of which presents a somewhat different view of a common dataset, and is used to analyze that information.** So, now that we have a grasp of what Dashboard means, we can elaborate more complex displays or Dashboards.   Part II: Risk analysis Dashboard Now let's create a more useful Dashboard. When we create a Dashboard, we always need to answer some basic questions such as:- What data do we want to display in our dashboard?- Who will use this dashboard?- Will it be used by different people?- What will it be used for?- What are the key features in our dashboard?- What useful comparisons should we show?- etc...So, first of all, we need to have a goal or aim with our dashboard. Once we know what we want to show, who will use it, and how do we want to display the information, we can start building the pieces of our Dashboard.In this part, we will go back into the Cryptocurrencies data, and try to build a risk indicator, that should help us with our investments. Disclaimer: This is no financial advise, we are building this for the purpose of teaching how to build effective Dashboards. Use this results at your own risk in case of investment. So first, let's load the data that we want to display, and plot it using `matplotlib` and `pandas` as this help us see what information we want to display in an easy and fast way.<jupyter_code>from pandas import read_csv, to_datetime

df = read_csv('data/external/Coinbase_ETHEUR_dailydata.csv', parse_dates=['datetime'])
df.head(2)<jupyter_output><empty_output><jupyter_text>Great, now we have the basic data, we have the low, high, open, close, and volume prices of Ethereum that we used in notebook 1. Since we are using time series data, we can use the "datetime" variable as the index of our dataframe:<jupyter_code>df = df.set_index('datetime').sort_index()
df.head(2)
import matplotlib.pyplot as plt

df.close.plot(figsize=(12, 4))
plt.grid(True, alpha=.2)
plt.show()<jupyter_output><empty_output><jupyter_text>So, first, we want to create useful and informative variables to show them in our dashboard. For this purpose, we create two variables. First, the "vol_fiat" variable, which is basically the product of the daily volume times the closing price, which is a proxy of the actual...<jupyter_code>df['vol_fiat'] = df['volume'] * df['close'] # multiply the ETH volume by closing price to approximate fiat volume
df.vol_fiat.plot(figsize=(12, 4))
plt.grid(True, alpha=.2)
plt.show()<jupyter_output><empty_output><jupyter_text>Next, we will create another variable that shows our own risk indicator, that is the ratio between the average price of the lat 30 days compared to the last 90 days. This gives a proxy of how much the prices has increased in the last month compared to the last month, showing when the price have grown too much, and is likely to correct over the next periods.<jupyter_code>df['risk_indicator'] = df['close'].rolling(window=30).mean().fillna(method='bfill') /\
                       df['close'].rolling(window=90).mean().fillna(method='bfill')
df.risk_indicator.describe()<jupyter_output><empty_output><jupyter_text>This variable is not normalized, in the sense that it ranges from 0.76 to 1.36. To make it more interpretable, we will normalize using a standarization, assuming that it follows a normal distribution. This variable is as follows:<jupyter_code>df['risk_indicator_normalized'] = (df['risk_indicator'] - df['risk_indicator'].mean()) / df['risk_indicator'].std()
df.risk_indicator_normalized.describe()<jupyter_output><empty_output><jupyter_text>Now we have a variable that ranges between -1.6 and 1.7. Let's make a scatterplot using as colors the risk that we just created:<jupyter_code>import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(12, 4))
plt.scatter(df.index, df.close, c=df.risk_indicator_normalized, cmap='RdBu_r', vmin=-1, vmax=1)
plt.colorbar()
plt.grid(True, alpha=.2)
plt.show()<jupyter_output><empty_output><jupyter_text>In this time scatter plot we have each dot representing a day (X-axis), the Y-axis indicates the average closing price of Ethereum, and the color indicates the "risk" that we calculated previously, where blue colors indicate that the price has remained stable in the last month compared to the last three months, whereas red colors indicate that the price is less stable. Now that we know what we want to plot, we will create this same chart in `plotly.express`.<jupyter_code>import plotly.express as px
px.scatter(df, x=df.index, y=df.close, color=df.risk_indicator_normalized, color_continuous_scale='RdBu_r')<jupyter_output><empty_output><jupyter_text>Notice that we are using a divergent colorscale to represent an attribute that changes in both directions from a middle point. We want this middle point 0, to match the white color on the scale. Thus, the colormap "RdBu_r" is appropriate. There are other Diverging Colormaps that you can find in [here](https://matplotlib.org/stable/tutorials/colors/colormaps.html).<jupyter_code># TODO: Explain the 2nd graph, and what vol_fiat does and why we want to show it. Why do we want to show them together?<jupyter_output><empty_output><jupyter_text>Next, we want to create another graph that can give us extra information about the risk. The second figure we are going to make is the Volume in Fiat (see this [link](https://en.wikipedia.org/wiki/Fiat_money) for further explanations.<jupyter_code>px.scatter(df, x=df.index, y=df.vol_fiat, color=df.risk_indicator_normalized, color_continuous_scale='RdBu_r')<jupyter_output><empty_output><jupyter_text>And now we will use these same graphs to make our own Dashboard!<jupyter_code>app.layout = html.Div(children=[
  html.H1(children='Our amazing risk indicator!', 
          style={'textAlign': 'center'}),
      html.H2(children='Risk indicator #1'),
      dcc.Graph(id='risk_indicator_1',
        figure=px.scatter(df,
                      x=df.index, 
                      y=df.close, 
                      color=df.risk_indicator_normalized, 
                      color_continuous_scale='RdBu_r'
                         )
            ),
      html.H2(children='Risk indicator #2'),
      dcc.Graph(id='vol_fiat_1',
        figure=px.scatter(df,
                      x=df.index,
                      y=df.vol_fiat, 
                      color=df.risk_indicator_normalized, 
                      color_continuous_scale='RdBu_r')
             )
  ])
app.run_server(mode='external', host = '127.0.0.1', port=8051, debug=True)<jupyter_output>Dash app running on http://127.0.0.1:8051/<jupyter_text>Great! Now we have created our first dashboard. We have simply joined two graphs into a Dashboard, to show different aspects of the risk that we want to represent.  Part 3: Adding more charts to our dashboard Add new graph with weekly data.<jupyter_code>df.resample('W').mean()['close'].plot(figsize=(12, 4), color='k', linestyle='--', linewidth=3)
plt.bar(df.resample('W').mean()['close'].index,
       df.resample('W').mean()['close'], alpha=.5, edgecolor='k')
plt.grid(True)
plt.show()
df_resampled_weekly = df.resample('W').mean()['close']
df_resampled_weekly.head()
df_last_days = df['close'].tail(8).diff(1).tail(7)
df_last_days.index = ['{}_days_ago'.format(j) for j in range(1, 8)]
from pandas import DataFrame

df_for_table = DataFrame(df_last_days)
import plotly.graph_objects as go
from numpy import round

fig = go.Figure(data=[go.Table(
        columnwidth = [30,30,30],
        header=dict(values=[i.replace('_', ' ') for i in df_for_table.T.columns.tolist()],
        line_color='darkslategray',
        align='center',
        font=dict(color='black', family="Lato", size=20),
        height=30
        ),
        cells=dict(values=round(df_for_table.T.values.tolist()[0], 2),
               line_color='darkslategray',
               align='left',
               font_color=[['green' if x > 0 else "red" if x < 0 else "blue"
                            ] for x in df_for_table.values],
       height=30
       ))
 ])


fig.show()<jupyter_output><empty_output><jupyter_text>Notice that when we introduce multiple charts, Dash automatically places them one on top of each other. If we want to arrange them differently we need to get into the `dash.html` module. Using bootstrap to make our dash adaptive to any screen resolution, we would need to use to use bootstrap and advanced html. In this exercises we will adjust the width and heigth of our charts manually.In case you want to dig deeper in this topic, here you can find more information https://dash-bootstrap-components.opensource.faculty.ai/docs/components/layout/<jupyter_code>app.layout = \
    html.Div(children=[
        html.H1(children='Our amazing risk indicator!', 
                      style={'textAlign': 'center'}),
        #first row
        html.Div(children=[
            # first row, first column
                html.H2(children='Risk indicator #1',style={'textAlign': 'center'}),
                dcc.Graph(id='risk_indicator_1',
                    figure=px.scatter(df,
                    x=df.index, 
                    y=df.close, 
                    color_continuous_midpoint=0,
                    color=df.risk_indicator_normalized, 
                    labels={'risk_indicator_normalized':'Risk', 'close':'Closing Price (€)', 'datetime':'Date'},
                    color_continuous_scale='RdBu_r',
                    width=1000, height=400, ### ADJUST THIS WIDTH AND HEIGHT ACCORDING TO YOUR SCREEN RESOLUTION
                         )
            )], style={'display':'inline-block'}),
            html.Div(children=[
            # first row, second column
                html.H2(children='Risk indicator #2',style={'textAlign': 'center'}),
                dcc.Graph(id='vol_fiat_1',
                    figure=px.scatter(df,
                    x=df.index,
                    y=df.vol_fiat, 
                    color_continuous_midpoint=0,
                    color=df.risk_indicator_normalized, 
                    labels={'risk_indicator_normalized':'Risk', 'vol_fiat':'Fiat Exchange Volume', 'datetime':'Date'},
                    color_continuous_scale='RdBu_r',
                    width=800, height=400) ### ADJUST THIS WIDTH AND HEIGHT ACCORDING TO YOUR SCREEN RESOLUTION
                        )], style={'display': 'inline-block'}),
    html.Div(children=[
        # second row
        html.Div(children=[
                # second row, first column
                html.H1(children='Weekly prices', style={'textAlign':'center'}),
                dcc.Graph(id='weeklyprices',
                          figure=px.line(df_resampled_weekly,
                                        x=df_resampled_weekly.index,
                                        y=df_resampled_weekly.values,
                                        labels={'y':'Price ETH (€)', 'datetime':'Date'}
                                        ))
            ]),
                # second row, second columns
                    html.Div(children= [
                        dcc.Graph(id='table', 
                                  figure=go.Figure(data=[go.Table(
                                    columnwidth = [30,30,30],
                                    header=dict(values=[i.replace('_', ' ') for i in df_for_table.T.columns.tolist()],
                                    # fill_color='#b9e2ff',
                                    line_color='darkslategray',
                                    align='center',
                                    font=dict(color='black', family="Lato", size=20),
                                    height=30 ### ADJUST THIS WIDTH AND HEIGHT ACCORDING TO YOUR SCREEN RESOLUTION
                                    ),
                                cells=dict(values=round(df_for_table.T.values.tolist()[0], 2),
                                       line_color='darkslategray',
                                       align='left',
                                       font_color=[['green' if x >0 else       
                                       "red" if x < 0 else "blue"
                                       ] for x in df_for_table.values],
                                       height=30 ### ADJUST THIS WIDTH AND HEIGHT ACCORDING TO YOUR SCREEN RESOLUTION
                                       ))
             ]))
        ]),        
        ])       
])
app.run_server(mode='external', host = '127.0.0.1', port=8051, debug=True)<jupyter_output>/Users/feliuserraburriel/opt/anaconda3/envs/barcelonaitacademy/lib/python3.9/site-packages/jupyter_dash/jupyter_app.py:139: UserWarning:

The 'environ['werkzeug.server.shutdown']' function is deprecated and will be removed in Werkzeug 2.1.
{'fraction_non_alphanumeric': 0.09577565207058404, 'fraction_numerical': 0.011348107658487315, 'mean_word_length': 2.999049655500119, 'pattern_counts': {'":': 0, '<': 66, '<?xml version=': 0, '>': 67, 'https://': 5, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 6, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 23, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '242081', 'license': 'MIT', 'n_tokens_mistral': 4921, 'n_tokens_neox': 4608, 'n_words': 1666, 'path': '5_Creating_dashboards_with_plotly_and_dash.ipynb', 'repo_name': 'Freegalado/data_visualization_python', 'size': '16839'}