e-mission / em-public-dashboard

A simple and stupid public dashboard prototype.
BSD 3-Clause "New" or "Revised" License
0 stars 23 forks source link

Labeled and Labeled & Inferred bars generation broken for `ca-ebike` #154

Open iantei opened 2 months ago

iantei commented 2 months ago
Issue with ca-ebike Stacked Bar Charts
Issue_1
Hint of the issue
Issue_2

For all the current deployment custom-labels including default label-options , label-options.json's MODE has "value":"other"

MODE: [
... ,
{"value":"other", "baseMode":"OTHER", "met_equivalent":"UNKNOWN", "kgCo2PerKm": 0}
]

EXCEPT ca-ebike for which it is "value":"other_mode"

MODE: [
... ,
{"value":"other_mode", "baseMode":"OTHER", "met_equivalent":"UNKNOWN", "kgCo2PerKm": 0}`
]

The issue is happening because of the dependency on the list of keys of MODE from the deployment-custom labels.

We are mapping the colors_mode and colors_replaced in the following way:

# In scaffolding.py: mapping_color_labels()
# Mapping between mode values and base_mode OR baseMode (backwards compatibility)
value_to_basemode = {mode["value"]: mode.get("base_mode", mode.get("baseMode", "UNKNOWN")) for mode in labels["MODE"]}

    colors_mode = emcdb.dedupe_colors([
        [mode, emcdb.BASE_MODES[value_to_basemode.get(mode, "UNKNOWN")]['color']]
        for mode in set(mode_values)
    ], adjustment_range=[1,1.8])

This way, colors_mode will have the mapping for other_mode:[color_palette_number] retrieved from the BASE_MODES, but will not have any mapping for other.

We generate other label to merge all small entries. Therefore, when we call the below function:

# In plots.py : plot_and_text_stacked_bar_chart()
bar = ax.barh(y=bar_label, width=mode_prop, height=bar_height, left=bar_width, label=values_to_translations.get(label, label), color=colors[label])

It can't find colors['other']. Therefore, resulting in the issue observed above.

iantei commented 2 months ago

Some possible solution and checks which can be incorporated to handle this issue:

mode_values =  ([mode["value"] for mode in labels["MODE"]] + ['other']) if "MODE" in labels else []
purpose_values = ([mode["value"] for mode in labels["PURPOSE"]] + ['other']) if "PURPOSE" in labels else []
replaced_values = ([mode["value"] for mode in labels["REPLACED_MODE"]] + ['other']) if "REPLACED_MODE" in labels else []

Since this other doesn't have baseMode, would it be appropriate to use "UNKNOWN"'s to represent this?