pumpwood-streamlit-pkg
Python Package to deploy Streamlit Dashboards at Pumpwood Systems.
Pumpwood is a native brasilian tree
which has a symbiotic relation with ants (Murabei)
This packages help to deploy Streamlit Dashboard associated with Pumpwood based Systems registering routes at Kong for single end-point for all microservice.
It implements an abstract class that should be inherited. When rendering the
dashboard, it uses cookie PumpwoodAuthorization to get authentication
token and validates if user is logged at Pumpwood Auth microservice. If
authentication token is not valid, authentication_error_page is
called to render unauthorized page.
Documentation Page
You can check the doc page here.
Example
Example using dashboard example made avaiable by Streamlit oficial website.
import os
import streamlit as st
import pandas as pd
import altair as alt
import plotly.express as px
from pumpwood_streamlit.dashboard import PumpwoodStreamlitDashboard
class Dashboard(PumpwoodStreamlitDashboard):
def set_page_config(self):
#######################
# Page configuration
st.set_page_config(
page_title="US Population Dashboard",
page_icon="🏂",
layout="wide",
initial_sidebar_state="expanded")
def main_view(self):
alt.themes.enable("dark")
#######################
# Load data
file_path = os.path.join(
os.path.dirname(__file__),
'data/us-population-2010-2019-reshaped.csv')
df_reshaped = pd.read_csv(file_path)
#######################
# Sidebar
with st.sidebar:
st.title('🏂 US Population Dashboard')
year_list = list(df_reshaped.year.unique())[::-1]
selected_year = st.selectbox('Select a year', year_list)
df_selected_year = df_reshaped[df_reshaped.year == selected_year]
df_selected_year_sorted = df_selected_year.sort_values(by="population", ascending=False)
color_theme_list = ['blues', 'cividis', 'greens', 'inferno', 'magma', 'plasma', 'reds', 'rainbow', 'turbo', 'viridis']
selected_color_theme = st.selectbox('Select a color theme', color_theme_list)
#######################
# Plots
# Heatmap
def make_heatmap(input_df, input_y, input_x, input_color, input_color_theme):
heatmap = alt.Chart(input_df).mark_rect().encode(
y=alt.Y(f'{input_y}:O', axis=alt.Axis(title="Year", titleFontSize=18, titlePadding=15, titleFontWeight=900, labelAngle=0)),
x=alt.X(f'{input_x}:O', axis=alt.Axis(title="", titleFontSize=18, titlePadding=15, titleFontWeight=900)),
color=alt.Color(f'max({input_color}):Q',
legend=None,
scale=alt.Scale(scheme=input_color_theme)),
stroke=alt.value('black'),
strokeWidth=alt.value(0.25),
).properties(width=900
).configure_axis(
labelFontSize=12,
titleFontSize=12
)
# height=300
return heatmap
# Choropleth map
def make_choropleth(input_df, input_id, input_column, input_color_theme):
choropleth = px.choropleth(input_df, locations=input_id, color=input_column, locationmode="USA-states",
color_continuous_scale=input_color_theme,
range_color=(0, max(df_selected_year.population)),
scope="usa",
labels={'population':'Population'}
)
choropleth.update_layout(
template='plotly_dark',
plot_bgcolor='rgba(0, 0, 0, 0)',
paper_bgcolor='rgba(0, 0, 0, 0)',
margin=dict(l=0, r=0, t=0, b=0),
height=350
)
return choropleth
# Donut chart
def make_donut(input_response, input_text, input_color):
if input_color == 'blue':
chart_color = ['#29b5e8', '#155F7A']
if input_color == 'green':
chart_color = ['#27AE60', '#12783D']
if input_color == 'orange':
chart_color = ['#F39C12', '#875A12']
if input_color == 'red':
chart_color = ['#E74C3C', '#781F16']
source = pd.DataFrame({
"Topic": ['', input_text],
"% value": [100-input_response, input_response]
})
source_bg = pd.DataFrame({
"Topic": ['', input_text],
"% value": [100, 0]
})
plot = alt.Chart(source).mark_arc(innerRadius=45, cornerRadius=25).encode(
theta="% value",
color= alt.Color("Topic:N",
scale=alt.Scale(
#domain=['A', 'B'],
domain=[input_text, ''],
# range=['#29b5e8', '#155F7A']), # 31333F
range=chart_color),
legend=None),
).properties(width=130, height=130)
text = plot.mark_text(align='center', color="#29b5e8", font="Lato", fontSize=32, fontWeight=700, fontStyle="italic").encode(text=alt.value(f'{input_response} %'))
plot_bg = alt.Chart(source_bg).mark_arc(innerRadius=45, cornerRadius=20).encode(
theta="% value",
color= alt.Color("Topic:N",
scale=alt.Scale(
# domain=['A', 'B'],
domain=[input_text, ''],
range=chart_color), # 31333F
legend=None),
).properties(width=130, height=130)
return plot_bg + plot + text
# Convert population to text
def format_number(num):
if num > 1000000:
if not num % 1000000:
return f'{num // 1000000} M'
return f'{round(num / 1000000, 1)} M'
return f'{num // 1000} K'
# Calculation year-over-year population migrations
def calculate_population_difference(input_df, input_year):
selected_year_data = input_df[input_df['year'] == input_year].reset_index()
previous_year_data = input_df[input_df['year'] == input_year - 1].reset_index()
selected_year_data['population_difference'] = selected_year_data.population.sub(previous_year_data.population, fill_value=0)
return pd.concat([selected_year_data.states, selected_year_data.id, selected_year_data.population, selected_year_data.population_difference], axis=1).sort_values(by="population_difference", ascending=False)
#######################
# Dashboard Main Panel
col = st.columns((1.5, 4.5, 2), gap='medium')
with col[0]:
st.markdown('#### Gains/Losses')
df_population_difference_sorted = calculate_population_difference(df_reshaped, selected_year)
if selected_year > 2010:
first_state_name = df_population_difference_sorted.states.iloc[0]
first_state_population = format_number(df_population_difference_sorted.population.iloc[0])
first_state_delta = format_number(df_population_difference_sorted.population_difference.iloc[0])
else:
first_state_name = '-'
first_state_population = '-'
first_state_delta = ''
st.metric(label=first_state_name, value=first_state_population, delta=first_state_delta)
if selected_year > 2010:
last_state_name = df_population_difference_sorted.states.iloc[-1]
last_state_population = format_number(df_population_difference_sorted.population.iloc[-1])
last_state_delta = format_number(df_population_difference_sorted.population_difference.iloc[-1])
else:
last_state_name = '-'
last_state_population = '-'
last_state_delta = ''
st.metric(label=last_state_name, value=last_state_population, delta=last_state_delta)
st.markdown('#### States Migration')
if selected_year > 2010:
# Filter states with population difference > 50000
# df_greater_50000 = df_population_difference_sorted[df_population_difference_sorted.population_difference_absolute > 50000]
df_greater_50000 = df_population_difference_sorted[df_population_difference_sorted.population_difference > 50000]
df_less_50000 = df_population_difference_sorted[df_population_difference_sorted.population_difference < -50000]
# % of States with population difference > 50000
states_migration_greater = round((len(df_greater_50000)/df_population_difference_sorted.states.nunique())*100)
states_migration_less = round((len(df_less_50000)/df_population_difference_sorted.states.nunique())*100)
donut_chart_greater = make_donut(states_migration_greater, 'Inbound Migration', 'green')
donut_chart_less = make_donut(states_migration_less, 'Outbound Migration', 'red')
else:
states_migration_greater = 0
states_migration_less = 0
donut_chart_greater = make_donut(states_migration_greater, 'Inbound Migration', 'green')
donut_chart_less = make_donut(states_migration_less, 'Outbound Migration', 'red')
migrations_col = st.columns((0.2, 1, 0.2))
with migrations_col[1]:
st.write('Inbound')
st.altair_chart(donut_chart_greater)
st.write('Outbound')
st.altair_chart(donut_chart_less)
with col[1]:
st.markdown('#### Total Population')
choropleth = make_choropleth(df_selected_year, 'states_code', 'population', selected_color_theme)
st.plotly_chart(choropleth, use_container_width=True)
heatmap = make_heatmap(df_reshaped, 'year', 'states', 'population', selected_color_theme)
st.altair_chart(heatmap, use_container_width=True)
with col[2]:
st.markdown('#### Top States')
st.dataframe(df_selected_year_sorted,
column_order=("states", "population"),
hide_index=True,
width=None,
column_config={
"states": st.column_config.TextColumn(
"States",
),
"population": st.column_config.ProgressColumn(
"Population",
format="%f",
min_value=0,
max_value=max(df_selected_year_sorted.population),
)}
)
with st.expander('About', expanded=True):
st.write('''
- Data: [U.S. Census Bureau](https://www.census.gov/data/datasets/time-series/demo/popest/2010s-state-total.html).
- :orange[**Gains/Losses**]: states with high inbound/ outbound migration for selected year
- :orange[**States Migration**]: percentage of states with annual inbound/ outbound migration > 50,000
''')
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pumpwood_streamlit-0.18.12.tar.gz.
File metadata
- Download URL: pumpwood_streamlit-0.18.12.tar.gz
- Upload date:
- Size: 18.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.4.1 CPython/3.12.13 Linux/6.17.0-1022-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71126a70248ba9ec5d97d8f8ceb5eff7821055c413d683457bf91859a6c14e1f
|
|
| MD5 |
3811cdb43e0e789ed71a9df8c5b5b674
|
|
| BLAKE2b-256 |
d02b240f28e2761c2188eaff4d46485738d41b259a169bbdeca233a1e30ba01b
|
File details
Details for the file pumpwood_streamlit-0.18.12-py3-none-any.whl.
File metadata
- Download URL: pumpwood_streamlit-0.18.12-py3-none-any.whl
- Upload date:
- Size: 21.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
poetry/2.4.1 CPython/3.12.13 Linux/6.17.0-1022-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a6c271845f4e514a738ed4f3b4f124f673802622e67e4217bdc82de8f4cedb22
|
|
| MD5 |
d02c8220496ff2bc260a752d700bcafc
|
|
| BLAKE2b-256 |
67383cf5444ff0636de01b67317a4c7ed11faaf3206061cf27cf3df91cef8019
|