I'm trying to calculate the mean center of population in the U.S. for a variety of variables, so my first step was to compute them for the last 10 years of population by county and see if they match up against the Census maps of this figure (at least roughly, since the Census is using a more granular geographic resolution.) As you'd expect, it's a sort of extremely delayed Manifest Destiny:
(The formula for calculating these points based on many population centers is on page 2 here, if anyone is curious.)
I'm migrating from R/RStudio to Jupyter, using pandas, plotly, numpy, etc. I'm normally a JavaScript engineer, but I'm comfortable with Python and like it quite a bit more than R! I was able to calculate what appear to be similar points, using the airport map example in this fantastic tutorial on plotly.graph_objects.Scattergeo, but I'm stuck at a national resolution so I can't tell how well I'm doing:
I can manually zoom, of course, but I'd really like to understand how to focus on only Missouri by default. I found this useful CodePen, but since there are so many different excellent mapping tools in Python I'm not sure how to port over the JS.
My current map, based on the above tutorial, sets up the basic plot and then modifies the layout's scope in a second line -- I'm not certain if this is standard for plotly, or just a convenience.
As much as I admire Python, going straight to the docs for update_layout is a bit of a rabbit hole :) I don't mind dictating the lat/lng bounds of the viewport, though it would neat to just say "Missouri." I realize this is simple -- just a bit of a learning curve.
import pandas as pd
import plotly.graph_objects as go
meanCenters = pd.read_json('{"year": {"0": 2010, "1": 2011, "2": 2012, "3": 2013, "4": 2014, "5": 2015, "6": 2016, "7": 2017, "8": 2018, "9": 2019}, "lat": {"0": 37.52908501121699, "1": 37.51719645600817, "2": 37.50264465332917, "3": 37.489564543614605, "4": 37.47311004581999, "5": 37.45358003505096, "6": 37.43623735876329, "7": 37.423475510154134, "8": 37.4121869670822, "9": 37.40021167050047}, "lng": {"0": -92.1522086893934, "1": -92.17800419530532, "2": -92.20484620692078, "3": -92.23312370193283, "4": -92.26617930383293, "5": -92.30498885605378, "6": -92.3395596061908, "7": -92.36398254029461, "8": -92.38362683728195, "9": -92.40337680455285}}')
fig = go.Figure(data=go.Scattergeo(
lon = meanCenters['lng'],
lat = meanCenters['lat'],
mode = 'markers'
))
fig.update_layout(
geo_scope='usa',
height=600
)
fig.show()
Data is included above -- thx, @vestland! -- but reprinted here for readability
year lat lng
2010 37.52908501121699 -92.1522086893934
2011 37.51719645600817 -92.17800419530532
2012 37.50264465332917 -92.20484620692078
2013 37.489564543614605 -92.23312370193283
2014 37.47311004581999 -92.26617930383293
2015 37.45358003505096 -92.30498885605378
2016 37.43623735876329 -92.3395596061908
2017 37.423475510154134 -92.36398254029461
2018 37.4121869670822 -92.38362683728195
2019 37.40021167050047 -92.40337680455285



