Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 3 census layers at output area granularity #301

Merged
merged 4 commits into from
Aug 2, 2023
Merged

Conversation

dabreegster
Copy link
Contributor

@dabreegster dabreegster commented Aug 2, 2023

Thanks to @cmconlan for finding and prepping the data. #286

This adds percent of households without a car, average cars per household, and population density, all at OA level from the 2021 census. Demo: https://acteng.github.io/atip/census_layers/browse.html

screencast.mp4

Design issues

There are lots of these, but I want to time-box focusing on this and move onto more requests, and also get feedback from users on what we've got so far. If there are any short-term improvements, happy to do!

Before even getting to the question of how to show these layers in conjunction with any loaded scheme data (which is a problem with all of the layers right now)...

  • We're using 3 checkboxes, but really they act like radio buttons, because you can only view one layer at a time. Alternatively we could have a checkbox for "census data at OA level" and then expose a dropdown or radio, but this makes discovering the layers harder.
  • The checkboxes are enormous and not part of the regular group, because we need to dynamically add the color legend beneath them. The govuk checkbox group component breaks when I tried that.
  • The scale for percent of households without a car and number of cars per household is flipped, so when you swap between the layers, the colors kind of invert. Potentially confusing?
  • The ONS map used as reference changes the buckets/scale as you zoom around. We don't do that; the buckets are fixed.
  • Things are choppy to load / move around, and the geometry is very simplified, at low zoom levels. It'd be better if we mimicked the ONS map and actually switched to using different data at lower granularity (like MSOA) when we're at low zoom.

It could be nice to have an optional for dasymetric maps instead of the choropleth, like nptscot.github.io. Consider it possible future work.

let outlineLayer = `${name}-outline`;
let colorScale = colors.sequential_low_to_high;

// Mutually exclusive, like a radio button
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awkward code-wise, but this gets us the best UX I can think of for the moment. Suggestions welcome.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree but I've just spent a decent chunk of time thinking about it I can't think of anything nicer. I'm maybe coming round to the idea of having it actually be a radio in some way but that has its own problems. Happy to leave as is for now

overwritePmtilesSource(
$map,
name,
`https://atip.uk/layers/v1/${name}.pmtiles`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's just one pmtiles file, with data for the 3 layers packed in.

}

// Should return 6 things (1 more than colorScale)
function makeLimits(): number[] {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Chris, I still need to fix my Python dependencies to run your script and see what the cut-offs for the bandings you used. I tried out different quantile functions in pandas, but they don't seem to handle the min / max value. For MapLibre, we have to set a real max value, or it uses a fallback color. So I've made some simple first choices here, but happy to iterate on them


function makeColorRamp(): any[] {
let limits = makeLimits();
let fillColor: any[] = ["step", ["get", colorBy]];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See https://maplibre.org/maplibre-style-spec/expressions/#step for reference... and note the docs don't match reality or the example code, because stop_output_0 is a lie. Instead there's a fallback value at the very end. I'll file an issue / send a PR to fix the docs...

<Checkbox
id="percent_households_without_car"
bind:checked={showHouseholdsWithoutCar}
on:change={() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual radio button logic :)

Copy link
Contributor

@yongrenjie yongrenjie Aug 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've not gotten the opportunity to use this Svelte feature yet, but I wonder if https://svelte.dev/tutorial/sharing-code might be useful here?! Might just be a complicated answer to a simple (or nonexistent) problem 🙃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh, thanks, that is clever! There could be a component wrapping these checkboxes. I'm not sure what the order would be though... does on:change happen after the checkbox state is toggled on? And in that shared stopOthers method, can we detect the "current" checkbox and keep it on? Maybe...

@@ -8,6 +8,15 @@ export const colors = {
combined_authorities: "cyan",
local_authority_districts: "orange",

// Color ramp from https://www.ons.gov.uk/census/maps/choropleth
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -149,6 +150,7 @@
<CombinedAuthoritiesLayerControl />
<LocalAuthorityDistrictsLayerControl />
</CheckboxGroup>
<CensusOutputAreaLayerControl />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I use the regular checkbox group above, the legends on different lines blow up:
Screenshot from 2023-08-02 13-04-48
Help welcome.

@Pete-Y-CS
Copy link
Contributor

Pete-Y-CS commented Aug 2, 2023

  • We're using 3 checkboxes, but really they act like radio buttons, because you can only view one layer at a time. Alternatively we could have a checkbox for "census data at OA level" and then expose a dropdown or radio, but this makes discovering the layers harder.

I think it's not terrible behaviour to have these switch off other latyers, I agree let the users see and focus on feedback they give.

  • The checkboxes are enormous and not part of the regular group, because we need to dynamically add the color legend beneath them. The govuk checkbox group component breaks when I tried that.

I could look into trying to do some bespoke styling to make it a little less misbehaving if you like?

  • The scale for percent of households without a car and number of cars per household is flipped, so when you swap between the layers, the colors kind of invert. Potentially confusing?

Hmm I think we can probably just invert households without a car? make it households with 1 or more car and then it's okay?

  • The ONS map used as reference changes the buckets/scale as you zoom around. We don't do that; the buckets are fixed.

Yeah I was wondering if we wanted to integrate LSOAs as well as OAs. Think another question for users when they have a go

  • Things are choppy to load / move around, and the geometry is very simplified, at low zoom levels. It'd be better if we mimicked the ONS map and actually switched to using different data at lower granularity (like MSOA) when we're at low zoom.

That would be better but again, as you said, no need to prematurely optimise before users tell us what they want, right?

@dabreegster
Copy link
Contributor Author

I could look into trying to do some bespoke styling to make it a little less misbehaving if you like?

If you have a spare moment, sure, but I think we could hold off. The flat list of layers is already too big; we won't be keeping this one CheckboxGroup for long

Hmm I think we can probably just invert households without a car? make it households with 1 or more car and then it's okay?

You're right, this will be more straightforward. It also matches the bandings Chris created originally! I'll make this change later today

Yeah I was wondering if we wanted to integrate LSOAs as well as OAs

The IMD and employment density data is at LSOA level, not OA, so we will have another layer for those soon. I think we can hold off on improving performance at low zooms for these layers right now, until we get feedback

…etter match the average car layer, and handle values of exactly the upper limit
@dabreegster dabreegster merged commit 764b074 into main Aug 2, 2023
2 checks passed
@dabreegster dabreegster deleted the census_layers branch August 2, 2023 16:00
@Robinlovelace
Copy link
Contributor

Great to see this and big 👍 from me, looking really strong.

@cmconlan
Copy link

cmconlan commented Aug 3, 2023

To add my comments on a few things:

  • Yes, agree we could change "Percentage without a car" to "percentage with at least 1 car" or something to this effect.
  • It would be a nice feature to switch out the granularity of the data depending on the zoom, but I expect most of the analysis performed in the tool will be very localised, so keeping it at the most granular level I think is fine. As has been mentioned we can see what feedback is from users in any case
  • Longer term i think it's a nice feature to change the scale so it's relative to whatever is in view, but I don't think it significantly detracts from the utility of the analysis so we not urgent I don't think
  • Think it's ok to have radio buttons, but UI may get confusing as we add more and more to it. Groupings would be nice.

Overall think it looks great - really happy with

No comments on code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants