# Building a Dashboard#

import pathlib
import numpy as np
import pandas as pd
import panel as pn
pn.extension('katex')

import hvplot.pandas # noqa


## Non-interactive components#

In this exercise you will first construct a number of Panel components and then lay them out as a non-interactive Panel dashboard, using the usual earthquakes dataset.

%%time
columns = ['time', 'mag', 'depth', 'latitude', 'longitude', 'place', 'type']
df = df.set_index(df.time)[columns]
most_severe = df[df.mag >= 7]


### Richter scale equation#

Next we will create a component to display the equation for the Richter scale definition. Declare the appropriate pane and assign it to the equation variable.

equation_string = '$M_L = log_{10}A - log_{10} A_0(\delta)$'

## Define a panel component containing the equation (Hint: Use the LaTeX pane)
equation = ...

## Display it

equation = pn.pane.LaTeX(equation_string)


### List the strongest earthquakes#

year = 2000

def strongest_earthquakes_fn(year):
year_df = df[(df.time.dt.year == year) & (df.mag > 7)]
return year_df.sort_values('mag', ascending=False).iloc[:5][['time', 'place', 'mag']].reset_index(drop=True)

## Create a panel component by calling the function with a particular year
strongest_earthquakes = ...

## Display it

strongest_earthquakes = pn.panel(strongest_earthquakes_fn(year))


### Display an iframe of a Google Map#

Hint

An iframe is an HTML tag.

def gmap_fn(year):
yearly_df = df[(df.time.dt.year == year)]
index = np.argmax(yearly_df.mag.fillna(0).values)
strongest = yearly_df.iloc[index]
lon, lat = strongest.longitude, strongest.latitude
return """
frameborder="0" scrolling="no" marginheight="0" marginwidth="0"></iframe>
""".format(lat=lat, lon=lon)

## Create a panel component by calling the function with a particular year and wrapping it in the appropriate pane
gmap = ...

## Display it


This example solution displays the map for the year (by default is the year 2000):

gmap = pn.panel(gmap_fn(year))


### A plot#

Here we create a plot from the year_df dataframe with .hvplot, create a Panel component, and assign it to the plot variable. We can visualize the distribution of earthquake magnitudes over the year by plotting the time variable on the x-axis and the mag variable on the y-axis.

year_df = df[df.time.dt.year == year]

## Create a plot and assign it to the plot variable
plot = ...

## Display it


This example solution uses concepts covered in the plotting section of the tutorial:

plot = year_df.hvplot.line(x='time', y='mag')


### Composing the static dashboard#

Now that we have defined all the different components, it is time to lay them out into the overall dashboard.

Arrange the following components into a dashboard using the Row and Column panels:

• logo

• equation

• strongest_earthquakes

• gmap

• plot

Hint

Remember that you can nest panel Row and Column layouts and use HSpacer and VSpacer objects to adjust spacing as necessary.

# Static Dashboard combining all the elements above.

year = 2000
logo_url = '../../assets/usgs_logo.png'
equation_string = '$M_L = log_{10}A - log_{10} A_0(\delta)$'

def strongest_earthquakes_fn(year):
year_df = df[(df.time.dt.year == year) & (df.mag > 7)]
return year_df.sort_values('mag', ascending=False).iloc[:5][['time', 'place', 'mag']].reset_index(drop=True)

def gmap_fn(year):
yearly_df = df[(df.time.dt.year == year)].fillna(0)
index = np.argmax(yearly_df.mag.fillna(0).values)
strongest = yearly_df.iloc[index]
lon, lat = strongest.longitude, strongest.latitude
return """
frameborder="0" scrolling="no" marginheight="0" marginwidth="0"></iframe>
""".format(lat=lat, lon=lon)

logo = pn.panel(logo_url, width=200)
equation = pn.pane.LaTeX(equation_string)
strongest_earthquakes = strongest_earthquakes_fn(year)
gmap = pn.pane.HTML(gmap_fn(year), height=300, width=300)
year_df = df[(df.time.dt.year == year) & (df.mag > 7)]
plot = year_df.hvplot.line(x='time', y='mag')

title = pn.panel('# Strongest Earthquakes in the Year %d' % year, width=400)

body_row1 = pn.Row(
pn.Column('### Richter scale definition', equation, '### Strongest Earthquake', gmap),
pn.Column('### Strongest Earthquakes', strongest_earthquakes),
)



### A dashboard with interactive widgets#

Having learned about how to create interactive components, we can now integrate them into dashboards. Here is one of the interactive plots from the last exercise:

depth_slider = pn.widgets.FloatSlider(name='Minimum depth', start=0, end=700, value=350)

dfi = most_severe.interactive(sizing_mode='stretch_width')
depth_filtered = dfi[dfi['depth'] < depth_slider]
depth_filtered_plot = depth_filtered.hvplot(y='mag', kind='scatter', color='red', marker='x')


Have a look at this object to remind you what it represents.

#### Adding a title and description#

Using the following markdown description of this plot, create a dashboard that integrates it together with an appropriate title, USGS logo and the interactive plot itself.

plot_description_markdown = """
This plot filters earthquakes according to the minimum depth
slider and displays the magnitude of the filtered earthquakes
over time. Note that only earthquakes with a magnitude >7
are shown.
"""

title = pn.panel('# Earthquake magnitude as function of depth')



### A dashboard filtering over year#

Now let us make a dashboard driven by a year slider. Create a integer slider that ranges from year 2000 to 2018 called year_slider.

Hint

You can use a pn.widgets.IntSlider to select the year.

year_slider = ...
# Display the slider

year_slider = pn.widgets.IntSlider(name='Year', start=2000, end=2018, value=2000)
year_slider


Now let use look at how the strongest_earthquakes_fn displays a DataFrame for the most severe earthquakes in a given yere:

year = 2000
most_severe_2000 = most_severe[most_severe.index.year == year]
most_severe_2000.sort_values('mag', ascending=False).iloc[:5][['time', 'place', 'mag']].reset_index(drop=True)


Using this as an example, create an equivalent table driven by year_slider, by declaring a filtered interactive DataFrame called year_idf. The handle on the result should be called year_table.

# Display the table above but with a selectable year using year_slider

year_slider = pn.widgets.IntSlider(name='Year', start=2000, end=2018, value=2000)
idf = most_severe.interactive()
year_idf = idf[idf.index.year == year_slider]
year_idf.sort_values('mag', ascending=False).iloc[:5][['time', 'place', 'mag']].reset_index(drop=True)

year_slider = pn.widgets.IntSlider(name='Year', start=2000, end=2018, value=2000)
idf = most_severe.interactive()
year_idf = idf[idf.index.year == year_slider]
year_table = year_idf.sort_values('mag', ascending=False).iloc[:5][['time', 'place', 'mag']].reset_index(drop=True)
year_table


Now create a scatter plot from year_idf with red cross (x) markers of size 50 called year_scatter.

Hint

Use a hvplot call with kind='scatter'. You also need to set the color and size keywords and set size=50.

# Create an interactive scatter called year_scatter

year_idf = idf[idf.index.year == year_slider]
year_scatter = year_idf.mag.hvplot(kind='scatter', color='red', marker='x', size=50)
year_scatter


#### Putting these components together#

Now using the terminal methods on our interactive dataframe together with a panel Markdown title and the Row and Column layout, we can now put year_slider, year_table and year_scatter together into a dashboard.

Hint

Remember that you can use the .panel() method on an interactive output to get the display without the slider. A single year_slider can then be displayed by a pn.Column.

# Build a dashboard using year_slider, year_table and year_scatter

year_idf = idf[idf.index.year == year_slider]

year_table = year_idf.sort_values('mag', ascending=False).iloc[:5][['time', 'place', 'mag']].reset_index(drop=True)
year_scatter = year_idf.mag.hvplot(kind='scatter', color='red', marker='x', size=50)
pn.Column('# Earthquake magnitudes by year ',
year_slider,
pn.Row(year_table.panel(), year_scatter.panel()))

This web page was generated from a Jupyter notebook and not all interactivity will work on this website. Right click to download and run locally for full Python-backed interactivity.