pumpwood-streamlit-pkg

Python Package to deploy Streamlit Dashboards at Pumpwood Systems

https://github.com/murabei-opensource-codes/pumpwood-streamlit-pkg

Science Score: 44.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (9.6%) to scientific vocabulary
Last synced: 9 months ago · JSON representation ·

Repository

Python Package to deploy Streamlit Dashboards at Pumpwood Systems

Basic Info
  • Host: GitHub
  • Owner: Murabei-OpenSource-Codes
  • License: bsd-3-clause
  • Language: Python
  • Default Branch: main
  • Size: 3.57 MB
Statistics
  • Stars: 0
  • Watchers: 0
  • Forks: 1
  • Open Issues: 0
  • Releases: 0
Created almost 2 years ago · Last pushed 11 months ago
Metadata Files
Readme Changelog License Citation

README.md

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 setpageconfig(self): ####################### # Page configuration st.setpageconfig( pagetitle="US Population Dashboard", pageicon="🏂", layout="wide", initialsidebarstate="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
                ''')

```

Owner

  • Name: Murabei Data Science
  • Login: Murabei-OpenSource-Codes
  • Kind: organization
  • Email: contact@murabei.com
  • Location: Brazil

Translating reality to math, a Data Science consulting company

Citation (CITATION.cff)

cff-version: 1.2.0
message: "If you use this software, please cite it as below."
authors:
  - family-names: Baceti
    given-names: André Andrade
title: "PumpWood Streamlit"

GitHub Events

Total
  • Delete event: 2
  • Push event: 10
  • Pull request review event: 1
  • Pull request event: 7
  • Create event: 8
Last Year
  • Delete event: 2
  • Push event: 10
  • Pull request review event: 1
  • Pull request event: 7
  • Create event: 8

Dependencies

setup.py pypi
  • streamlit *
src/pumpwood_streamlit.egg-info/requires.txt pypi
  • extra-streamlit-components *
  • streamlit *