Skip to content

Commit

Permalink
Fix Histogram Binning (#2086)
Browse files Browse the repository at this point in the history
Makes the following changes to the histogram tile:

1. Adds support for binning when dates include days (YYYY-MM-DD)
2. Don't show histogram if there's no data to show

Before:
![Screenshot 2023-01-23 at 1 30 28
PM](https://user-images.githubusercontent.com/4034366/214154740-011dd3c5-a631-4bfd-a491-c0ca4699dff8.png)

After:
![Screenshot 2023-01-23 at 1 32 36
PM](https://user-images.githubusercontent.com/4034366/214154763-f33d675e-1b2d-49b0-a8ef-c28dbe251cfe.png)

Before:
![Screenshot 2023-01-23 at 1 34 04
PM](https://user-images.githubusercontent.com/4034366/214154957-49c4e125-fb5d-4720-82f7-4da17c7aa7d9.png)

After:
![Screenshot 2023-01-23 at 1 34 16
PM](https://user-images.githubusercontent.com/4034366/214154994-98946575-4149-4a6e-93e5-86a5b15aeeb5.png)
  • Loading branch information
juliawu authored Feb 10, 2023
1 parent b371204 commit a5f89b1
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 289 deletions.
88 changes: 49 additions & 39 deletions server/config/disaster_dashboard/Earth.textproto
Original file line number Diff line number Diff line change
Expand Up @@ -231,11 +231,13 @@ categories {
event_type_keys: "drought"
}
}
# tiles {
# type: HISTOGRAM
# title: "SPI - 9 month"
# stat_var_key: "spi_9"
# }
tiles {
type: HISTOGRAM
title: "Number of droughts"
histogram_tile_spec {
event_type_key: "drought"
}
}
}
columns {
tiles {
Expand Down Expand Up @@ -274,14 +276,14 @@ categories {
event_type_keys: "fire"
}
}
tiles {
type: HISTOGRAM
title: "Number of fires"
histogram_tile_spec {
event_type_key: "fire"
}
}
# tiles {
# # TODO: Need to specify P1Y
# type: HISTOGRAM
# title: "Number of fires last year"
# stat_var_key: "fire_count"
# }
# tiles {
# # TODO: Need to specify P1Y
# type: HISTOGRAM
# title: "Total area affected by fires last year"
# stat_var_key: "fire_area"
Expand Down Expand Up @@ -331,14 +333,14 @@ categories {
event_type_keys: "flood"
}
}
tiles {
type: HISTOGRAM
title: "Number of floods"
histogram_tile_spec {
event_type_key: "flood"
}
}
# tiles {
# # TODO: Need to specify P1Y
# type: HISTOGRAM
# title: "Number of floods last year"
# stat_var_key: "flood_count"
# }
# tiles {
# # TODO: Need to specify P1Y
# type: HISTOGRAM
# title: "Total area affected by floods last year"
# stat_var_key: "flood_area"
Expand Down Expand Up @@ -388,11 +390,13 @@ categories {
event_type_keys: "storm"
}
}
# tiles {
# type: HISTOGRAM
# title: "Number of cyclones last year"
# stat_var_key: "cyclone_all"
# }
tiles {
type: HISTOGRAM
title: "Number of cyclones"
histogram_tile_spec {
event_type_key: "storm"
}
}
}
columns {
tiles {
Expand Down Expand Up @@ -432,11 +436,13 @@ categories {
event_type_keys: "wetbulb"
}
}
# tiles {
# type: HISTOGRAM
# title: "Number of wet bulb events last year"
# stat_var_key: "wetbulb_count"
# }
tiles {
type: HISTOGRAM
title: "Number of wet bulb events"
histogram_tile_spec {
event_type_key: "wetbulb"
}
}
# tiles {
# type: HISTOGRAM
# title: "Total area affected by wet bulb events last year"
Expand Down Expand Up @@ -485,11 +491,13 @@ categories {
event_type_keys: "heat"
}
}
# tiles {
# type: HISTOGRAM
# title: "Number of extreme heat events last year"
# stat_var_key: "heat_count"
# }
tiles {
type: HISTOGRAM
title: "Number of extreme heat events"
histogram_tile_spec {
event_type_key: "heat"
}
}
# tiles {
# type: HISTOGRAM
# title: "Total area affected by extreme heat events last year"
Expand Down Expand Up @@ -537,11 +545,13 @@ categories {
event_type_keys: "cold"
}
}
# tiles {
# type: HISTOGRAM
# title: "Number of extreme cold events last year"
# stat_var_key: "cold_count"
# }
tiles {
type: HISTOGRAM
title: "Number of extreme cold events"
histogram_tile_spec {
event_type_key: "cold"
}
}
# tiles {
# type: HISTOGRAM
# title: "Total area affected by extreme cold events last year"
Expand Down
7 changes: 6 additions & 1 deletion server/config/subject_page.proto
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ message DisasterEventMapTileSpec {
repeated string event_type_keys = 1;
}

message HistogramTileSpec {
string event_type_key = 1;
}

message TopEventTileSpec {
// Key for event type specs defined in the PageMetadata that should be displayed
// Ranked by severity prop.
Expand Down Expand Up @@ -147,7 +151,7 @@ message Tile {
DESCRIPTION = 8;
// allowed in BlockTypes: TYPE_NONE
HISTOGRAM = 10;
// allowed in BlockTypes: TYPE_NONE
// allowed in BlockTypes: DISASTER_EVENT
PLACE_OVERVIEW = 11;
// allowed in BlockTypes: DISASTER_EVENT
TOP_EVENT = 12;
Expand All @@ -170,6 +174,7 @@ message Tile {
DisasterEventMapTileSpec disaster_event_map_tile_spec = 6;
TopEventTileSpec top_event_tile_spec = 8;
ScatterTileSpec scatter_tile_spec = 9;
HistogramTileSpec histogram_tile_spec = 10;
}
}

Expand Down
44 changes: 23 additions & 21 deletions server/config/subject_page_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

78 changes: 0 additions & 78 deletions server/routes/api/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,58 +22,6 @@
bp = Blueprint("series", __name__, url_prefix='/api/observations/series')


# TODO(juliawu): Handle case where dates are not "YYYY-MM"
# TODO(juliawu): We should adjust how we bin based on the data,
# instead of cutting it off.
def get_binned_series(entities, variables, year):
"""Get observation series for entities and variables, for a given year.
Bins observations from a series for plotting in the histogram tile.
Currently, binning is done by only returning observations for a given year.
This is done by assuming the dates of the series are in 'YYYY-MM' format,
filtering for observations from the given year, and then imputing 0 for
any months missing, up to the end of the series.
Note: This assumes the dates of the series are in 'YYYY-MM' format.
Args:
entities (list): DCIDs of entities to query
variables (list): DCIDs of variables to query
year (str): year in "YYYY" format to get observations for
Returns:
JSON response from server, with series containing only observations from
the specified year.
"""
# Get raw series from mixer
data = util.series_core(entities, variables, False)

for stat_var in variables:
for location in data['data'][stat_var].keys():

# filter series to just observations from the selected year
series = data['data'][stat_var][location]['series']
pruned_series = []
dates_with_data = []
for obs in series:
if obs['date'][:4] == year:
pruned_series.append(obs)
dates_with_data.append(obs['date'])

if len(pruned_series) > 0:
# fill in missing periods with 0s, from January to end of series
last_month = int(dates_with_data[-1][-2:])
months_to_fill = [str(mm).zfill(2) for mm in range(1, last_month + 1)]
for month in months_to_fill:
date = f"{year}-{month}"
if date not in dates_with_data:
pruned_series.append({'date': date, 'value': 0})
pruned_series.sort(key=lambda x: x['date'])

data['data'][stat_var][location]['series'] = pruned_series
return data


@bp.route('', strict_slashes=False)
@cache.cached(timeout=3600 * 24, query_string=True)
def series():
Expand Down Expand Up @@ -105,7 +53,6 @@ def series_all():
def series_within():
"""Gets the observation for child entities of a certain place
type contained in a parent entity at a given date.
Note: the perferred facet is returned.
"""
parent_entity = request.args.get('parent_entity')
Expand All @@ -125,7 +72,6 @@ def series_within():
def series_within_all():
"""Gets the observation for child entities of a certain place
type contained in a parent entity at a given date.
Note: all the facets are returned.
"""
parent_entity = request.args.get('parent_entity')
Expand All @@ -138,27 +84,3 @@ def series_within_all():
if not variables:
return 'error: must provide a `variables` field', 400
return util.series_within_core(parent_entity, child_type, variables, True)


@bp.route('/binned')
@bp.route('/binned/<path:year>')
def series_binned(year='2022'):
"""Get observations binned by time-period.
Used for pre-binning data for the histogram tile. Currently only "bins" data
by returning only observations from a specific year.
Args:
year: the year to get observations for
Returns:
JSON response from server, with series containing only observations from
the specified year.
"""
entities = list(filter(lambda x: x != "", request.args.getlist('entities')))
variables = list(filter(lambda x: x != "", request.args.getlist('variables')))
if not entities:
return 'error: must provide a `entities` field', 400
if not variables:
return 'error: must provide a `variables` field', 400
return get_binned_series(entities, variables, year)
Loading

0 comments on commit a5f89b1

Please sign in to comment.