Skip to content

Commit

Permalink
Merge pull request #69 from unicef-drp/average_line
Browse files Browse the repository at this point in the history
Average line
  • Loading branch information
Amy-Reidy authored Jul 3, 2024
2 parents 128427b + 0ca8dbd commit 936812e
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 19 deletions.
56 changes: 44 additions & 12 deletions dash_service/pages/transmonee.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@

years = list(range(2000, 2025))

# some indexes have been listed as ratios in SDG database so we need to specify not to round these indicators
codes_3_decimals = ['HVA_EPI_INF_RT_0-14', 'EDU_SE_TOT_GPI_L2_MAT', 'EDU_SE_TOT_GPI_L2_REA', 'EDU_SE_AGP_CPRA_L3']
codes_1_decimal = ['DM_FRATE_COMP', 'PV_GINI_COEF']

# a key:value dictionary of countries where the 'key' is the country name as displayed in the selection
# tree whereas the 'value' is the country name as returned by the sdmx list: https://sdmx.data.unicef.org/ws/public/sdmxapi/rest/codelist/UNICEF/CL_COUNTRY/1.0
countries_iso3_dict = {
Expand Down Expand Up @@ -1060,10 +1064,6 @@ def get_data(
data["OBS_FOOTNOTE"] = data.OBS_FOOTNOTE.str.wrap(70).str.replace("\n", "<br>")
data["DATA_SOURCE"] = data.DATA_SOURCE.str.wrap(70).str.replace("\n", "<br>")

# some indexes have been listed as ratios in SDG database so we need to specify not to round these indicators
codes_3_decimals = ['HVA_EPI_INF_RT_0-14', 'EDU_SE_TOT_GPI_L2_MAT', 'EDU_SE_TOT_GPI_L2_REA', 'EDU_SE_AGP_CPRA_L3']
codes_1_decimal = ['DM_FRATE_TOT', 'PV_GINI_COEF']

if "IDX" in data.UNIT_MEASURE.values or any(code in data.CODE.values for code in codes_3_decimals):
data.OBS_VALUE = data.OBS_VALUE.round(3)
elif any(code in data.CODE.values for code in codes_1_decimal):
Expand Down Expand Up @@ -1515,7 +1515,7 @@ def get_base_layout(**kwargs):
),
],
style={"display":"flex", "justify-content":"center"},
lg=10, md=10, sm=12, xs=12
lg=12, md=12, sm=12, xs=12
),
dbc.Col(width=1),
],
Expand Down Expand Up @@ -2631,6 +2631,7 @@ def fig_options(indicator):
# Use base_indicator for the rest of the function
indicator_config = indicators_config.get(indicator, {})


# Check if the indicator has is string type and give only bar and map as options
if indicator_config and nominal_data(indicator_config):
area_types = [
Expand All @@ -2644,7 +2645,10 @@ def fig_options(indicator):
{"label": "Trend data", "value": "line"},
{"label": "Map of data", "value": "map"},
]
default_graph = "bar"
if indicator == 'DM_POP_NETM':
default_graph = "map"
else:
default_graph = "bar"

return area_types, default_graph

Expand Down Expand Up @@ -2869,6 +2873,8 @@ def aio_area_figure(
"",
)

data['type'] = 'country'

# indicator card
card_key = indicator

Expand Down Expand Up @@ -2907,8 +2913,8 @@ def aio_area_figure(
df_indicator_sources = df_sources[df_sources["Code"] == base_indicator]
unique_indicator_sources = df_indicator_sources["Source_Full"].unique()

if data["CODE"].isin(["DM_CHLD_POP", "DM_CHLD_POP_PT", "DM_ADOL_POP", "DM_UFIVE_POP"]).any():
source = " Multiple Sources"
if data["CODE"].isin(["DM_CHLD_POP", "DM_CHLD_POP_PT", "DM_FRATE_COMP","DM_ADOL_POP", "DM_UFIVE_POP"]).any():
source = "Multiple Sources"
elif len(unique_indicator_sources) > 0:
source = "; ".join(list(unique_indicator_sources))
else:
Expand All @@ -2917,7 +2923,7 @@ def aio_area_figure(
source_link = (
df_indicator_sources["Source_Link"].unique()[0]
if len(unique_indicator_sources) > 0
and not data["CODE"].isin(["DM_CHLD_POP", "DM_CHLD_POP_PT", "DM_ADOL_POP", "DM_UFIVE_POP"]).any()
and not data["CODE"].isin(["DM_CHLD_POP", "DM_CHLD_POP_PT", "DM_FRATE_COMP", "DM_ADOL_POP", "DM_UFIVE_POP"]).any()
else "https://ec.europa.eu/eurostat/cache/metadata/en/demo_pop_esms.htm"
)

Expand Down Expand Up @@ -3123,9 +3129,25 @@ def aio_area_figure(
options["text_auto"] = False
if (data['OBS_VALUE'] == 0).any():
graph_info = graph_info + "Zero values not showing on graph; see 'Countries with data' for more information."

if fig_type == "bar" and not dimension and "PS" not in data.UNIT_MEASURE.values:
# Calculate the average of the 'Value' column
average_value = data["OBS_VALUE"].mean()

if "IDX" in data.UNIT_MEASURE.values or any(code in data.CODE.values for code in codes_3_decimals):
average_value = round(average_value, 3)
#elif any(code in data.CODE.values for code in codes_1_decimal):
#average_value = round(average_value, 1)
else:
average_value = round(average_value, 1)

# Convert to int if there are no decimals
#if average_value == round(average_value):
# average_value = int(average_value)

# removing zero values from bar chart as they cause a bug where countries without data display on chart
fig_data = data[data['OBS_VALUE'] != 0] if fig_type == "bar" else data
print(fig_data)

if fig_type == "count_bar":
# change to fig type to generate px.bar
Expand All @@ -3137,18 +3159,28 @@ def aio_area_figure(
fig.update_layout(yaxis_title=y_axis_title)
# remove x-axis title but keep space below
fig.update_layout(xaxis_title="")
if fig_type == "bar" and not dimension and "YES_NO" not in data.UNIT_MEASURE.values and base_indicator != 'PP_SG_NHR_STATUS':
if fig_type == "bar" and not dimension and "YES_NO" not in fig_data.UNIT_MEASURE.values and base_indicator != 'PP_SG_NHR_STATUS':
fig.update_traces(marker_color=domain_colour)
fig.update_layout(showlegend=False)
if "PS" not in fig_data.UNIT_MEASURE.values:
annotation_text = f"Average: {average_value}% " if any(unit in fig_data.UNIT_MEASURE.values for unit in ["PCNT", "GOV_EXP_EDU"]) else f"Average: {average_value}"
fig.add_hline(
y=average_value,
line_color="#1cabe2",
line_width=2,
line_dash="dot",
annotation_text=annotation_text,
annotation_position="top right"
)
if fig_type == "line":
fig.update_traces(**traces)
# adding invisible line at zero to make sure the y-axis starts at zero
fig.add_hline(y=-0.3, line_color="rgba(0,0,0,0)")

fig.update_traces(hovertemplate=hovertext)

if fig_type == "bar" and "YES_NO" in data.UNIT_MEASURE.values:
dfs = data.groupby("Status").count()
if fig_type == "bar" and "YES_NO" in fig_data.UNIT_MEASURE.values:
dfs = fig_data.groupby("Status").count()
fig.add_trace(
go.Scatter(
x=dfs.index,
Expand Down
2 changes: 1 addition & 1 deletion dash_service/static/crm_framework_indicators.json
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@
},
{
"Indicator Name": "Total fertility rate",
"Code": "DM_FRATE_TOT"
"Code": "DM_FRATE_COMP"
},
{
"Indicator Name": "Number of births",
Expand Down
2 changes: 1 addition & 1 deletion dash_service/static/indicator_buttons.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"DM_CHLD_YOUNG_COMP_POP": NaN,
"DM_CHLD_YOUNG_POP": NaN,
"DM_CHLD_POP_PT": "Children as a share of the total population",
"DM_FRATE_TOT": "Total fertility rate",
"DM_FRATE_COMP": "Total fertility rate",
"DM_BRTS": "Number of births",
"DM_SP_POP_BRTH_MF": NaN,
"DM_LIFE_EXP": NaN,
Expand Down
2 changes: 1 addition & 1 deletion dash_service/static/indicator_definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"DM_CHLD_YOUNG_COMP_POP": "Compiled child, young people and total population, 0-17 and 18-24 years (1989-present)",
"DM_CHLD_YOUNG_POP": "Child and young people population, 0-17 and 18-24 years, at the beginning of the year",
"DM_CHLD_POP_PT": "Children as a percentage of the total population compiled from multiple sources. Figures for male and female represent the share of the male and female population respectively. Data comes from Eurostat, UN DESA or in some cases it has been directly submitted by the NSO (for Belarus, Georgia and Tajikistan).",
"DM_FRATE_TOT": "Average number of live births a hypothetical cohort of women (aged 15-49 years) would have at the end of their reproductive period if they were subject during their whole lives to the fertility rates of a given period and if they were not subject to mortality",
"DM_FRATE_COMP": "Total fertility rate is computed by adding the age specific fertility rates for women in a given year. It can be interpreted as the mean number of children that would be born alive to a woman during her lifetime if she were to pass through her childbearing years conforming to the fertility rates by age of a given year, and surviving. Data is compiled from multiple sources (Eurostat & UN DESA).",
"DM_BRTS": "Number of births (in thousands)",
"DM_SP_POP_BRTH_MF": "Sex ratio at birth refers to male births per female births. The data are for 5 year averages.",
"DM_LIFE_EXP": "Average number of years newborn children would live if subject to the mortality risks prevailing for the cross section of population at the time of their birth",
Expand Down
4 changes: 2 additions & 2 deletions dash_service/static/page_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
"yaxis": 'Number of births',
'button_name': 'Number of births'},
{'name': 'Total fertility rate',
'indicator': 'DM_FRATE_TOT',
'indicator': 'DM_FRATE_COMP',
'suffix': min_max_card_suffix,
'min_max': True,
"yaxis": 'Total fertility rate',
Expand All @@ -164,7 +164,7 @@
'indicators': ['DM_CHLD_POP',
'DM_CHLD_POP_PT',
'DM_BRTS',
'DM_FRATE_TOT',
'DM_FRATE_COMP',
'DM_POP_NETM'],
'default_graph': 'bar',
'default': 'DM_CHLD_POP'}},
Expand Down
2 changes: 1 addition & 1 deletion dash_service/static/structured_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@
"Indicator Name": "Percentage of children as a share of the total population"
},
{
"Code": "DM_FRATE_TOT",
"Code": "DM_FRATE_COMP",
"Indicator Name": "Total fertility rate (average live births per woman aged 15-49)"
},
{
Expand Down
2 changes: 1 addition & 1 deletion dash_service/tmp/transmonee - Copia.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ def get_data(

if "IDX" in data.UNIT_MEASURE.values or "HVA_EPI_INF_RT_0-14" in data.CODE.values:
data.OBS_VALUE = data.OBS_VALUE.round(3)
elif "DM_FRATE_TOT" in data.CODE.values:
elif "DM_FRATE_COMP" in data.CODE.values:
data.OBS_VALUE = data.OBS_VALUE.round(1)
else:
data.OBS_VALUE = data.OBS_VALUE.round(1)
Expand Down

0 comments on commit 936812e

Please sign in to comment.