Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into adai/update-dropdowns
Browse files Browse the repository at this point in the history
  • Loading branch information
alyssadai committed Jun 8, 2024
2 parents 12bcf76 + b72fa45 commit c786387
Show file tree
Hide file tree
Showing 9 changed files with 415 additions and 192 deletions.
111 changes: 101 additions & 10 deletions climate_emotions_map/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import dash_mantine_components as dmc
from dash import (
ALL,
Dash,
Input,
Output,
Expand All @@ -11,14 +12,19 @@
ctx,
no_update,
)
from dash.exceptions import PreventUpdate

from . import utility as utils
from .data_loader import NATIONAL_SAMPLE_SIZE, SURVEY_DATA
from .layout import construct_layout
from .layout import SINGLE_SUBQUESTION_FIG_KW, construct_layout
from .make_descriptive_plots import make_descriptive_plots
from .make_map import make_map
from .make_stacked_bar_plots import make_stacked_bar
from .utility import DEFAULT_QUESTION # IMPACT_COLORMAP,; OPINION_COLORMAP,
from .utility import ( # IMPACT_COLORMAP,; OPINION_COLORMAP,
ALL_STATES_LABEL,
DEFAULT_QUESTION,
SECTION_TITLES,
)

# Currently needed by DMC, https://www.dash-mantine-components.com/getting-started#simple-usage
_dash_renderer._set_react_version("18.2.0")
Expand All @@ -41,18 +47,31 @@
Output("party-stratify-switch", "disabled"),
],
[
Input("us-map", "clickData"),
Input("party-stratify-switch", "checked"),
Input("state-select", "value"),
],
prevent_initial_call=True,
)
def disable_state_select_and_party_switch_interaction(
is_party_stratify_checked, selected_state
def update_state_and_disable_state_select_and_party_switch_interaction(
figure, is_party_stratify_checked, selected_state
):
"""
Disable the state dropdown when the party stratify switch is checked,
Update the state dropdown when a specific state is clicked (if party stratify switch is not checked),
disable the state dropdown when the party stratify switch is checked,
and disable the party stratify switch when a specific state is selected (i.e., not None).
"""
if ctx.triggered_id == "us-map":
map_selected_state = figure["points"][0]["customdata"][0]

if is_party_stratify_checked or map_selected_state == selected_state:
raise PreventUpdate
return (
map_selected_state,
no_update,
False,
True,
)
if ctx.triggered_id == "party-stratify-switch":
# Deselect any state
return None, is_party_stratify_checked, no_update, no_update
Expand Down Expand Up @@ -80,7 +99,7 @@ def drawer_toggle(n_clicks, opened):
def update_drawer_state(value):
"""Callback function for updating the state in the drawer."""
if value is None:
return "National"
return ALL_STATES_LABEL
return f"State: {value}"


Expand Down Expand Up @@ -179,7 +198,7 @@ def update_map(question_value, state, impact):


@callback(
Output("stacked-bar-plot", "figure"),
Output("selected-question-bar-plot", "figure"),
[
Input("question-select", "value"),
Input("state-select", "value"),
Expand All @@ -188,13 +207,13 @@ def update_map(question_value, state, impact):
],
prevent_initial_call=True,
)
def update_stacked_bar_plots(
def update_selected_question_bar_plot(
question_value,
state,
is_party_stratify_checked,
show_all_responses_checked,
):
"""Update the stacked bar plots based on the selected question."""
"""Update the stacked bar plot for the selected question based on the selected criteria."""
question, subquestion = utils.extract_question_subquestion(question_value)

if show_all_responses_checked:
Expand All @@ -208,10 +227,82 @@ def update_stacked_bar_plots(
state=state,
stratify=is_party_stratify_checked,
threshold=threshold,
binarize_threshold=True,
fig_kw=SINGLE_SUBQUESTION_FIG_KW,
)
return figure


@callback(
Output("selected-question-title", "children"),
Input("state-select", "value"),
prevent_initial_call=True,
)
def update_selected_question_title(state):
"""Update the title for the selected question based on the selected state."""
if state is None:
return f"{SECTION_TITLES['selected_question']}, {ALL_STATES_LABEL}"
return f"{SECTION_TITLES['selected_question']}, {state}"


@callback(
Output("selected-question-container", "display"),
Input("impact-select", "value"),
prevent_initial_call=True,
)
def toggle_selected_question_bar_plot_visibility(impact):
"""Toggle visibility of the selected question bar plot component based on whether an impact is selected."""
if impact is not None:
return "none"
return "flex"


@callback(
Output("all-questions-title", "children"),
Input("state-select", "value"),
)
def update_all_questions_title(state):
"""Update the title for the section for all questions based on the selected state."""
if state is None:
return f"{SECTION_TITLES['all_questions']}, {ALL_STATES_LABEL}"
return f"{SECTION_TITLES['all_questions']}, {state}"


@callback(
Output({"type": "stacked-bar-plot", "question": ALL}, "figure"),
[
Input("state-select", "value"),
Input("party-stratify-switch", "checked"),
Input("response-threshold-control", "checked"),
],
prevent_initial_call=True,
)
def update_stacked_bar_plots(
state,
is_party_stratify_checked,
show_all_responses_checked,
):
"""Update the stacked bar plots for all questions based on the selected criteria."""
figures = []
for output in ctx.outputs_list:
# Example: {'id': {'question': 'q2', 'type': 'stacked-bar-plot'}, 'property': 'figure'}
question = output["id"]["question"]

if show_all_responses_checked:
threshold = None
elif not show_all_responses_checked:
threshold = DEFAULT_QUESTION["outcome"]

figure = make_stacked_bar(
question=question,
subquestion="all",
state=state,
stratify=is_party_stratify_checked,
threshold=threshold,
)
figures.append(figure)

return figures


if __name__ == "__main__":
app.run(debug=True)
9 changes: 9 additions & 0 deletions climate_emotions_map/data_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ def get_subquestion_order():
return subquestion_order


def get_domain_text() -> dict[str, str]:
"""Return a dictionary where key-value pairs are short and full names of each available domain."""
df = DATA_DICTIONARIES["question_dictionary.tsv"]
df_unique = df[["domain_short", "domain_text"]].drop_duplicates()
return dict(zip(df_unique["domain_short"], df_unique["domain_text"]))


SURVEY_DATA = load_survey_data()
# NOTE: column dtypes for opinions data TSVs
# Input:
Expand Down Expand Up @@ -144,5 +151,7 @@ def get_subquestion_order():
# ignore bool
# dtype: object

DOMAIN_TEXT = get_domain_text()

NATIONAL_SAMPLE_SIZE = SURVEY_DATA["samplesizes_state.tsv"]["n"].sum()
GEOJSON_OBJECTS = load_geojson_objects()
Loading

0 comments on commit c786387

Please sign in to comment.