Plotly:如何为Scattergeo设置手动边界框?

5

我正在尝试计算美国人口的平均中心,涉及多种变量,因此我的第一步是计算过去10年每个县的人口,并查看它们是否与普查地图上的数字相匹配(至少大致匹配,因为普查使用了更细粒度的地理分辨率)。正如你所预期的那样,这是一种极其延迟的“命运共同体”:

enter image description here

这些点的计算公式基于许多人口中心,如果有人感兴趣,请参见此处第2页。我正在从R/RStudio迁移到Jupyter,使用pandas、plotly、numpy等工具。我通常是一名JavaScript工程师,但我对Python很熟悉,并且比R更喜欢它!我能够计算出类似的点,使用了这个关于plotly.graph_objects.Scattergeo的绝妙教程中的机场地图示例,但我在国家分辨率上卡住了,所以我无法确定我的计算结果有多好。

enter image description here

当然,我可以手动缩放,但我真的很想了解如何默认只关注于密苏里州。我发现这个 有用的 CodePen,但由于Python中有许多不同的优秀地图工具,我不确定如何移植JS。

基于上面的教程,我的当前地图设置了基本图,并在第二行修改了布局范围 -- 我不确定这是plotly的标准,还是一个便利。

尽管我很钦佩Python,但直接查看update_layout文档有点像进入了一个兔子洞 :)。虽然我不介意指定视口的纬度/经度边界,但只说“密苏里州”会更好。我知道这很简单--只是需要一点学习曲线。

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()

数据包含在上面--感谢@vestland!--但为了易读性,在此重印。
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

嗨!关于如何分享数据样本,我有一个小提示;假设meanCenters是一个pandas数据框,请运行meanCenters.to_dict()并分享输出结果,同时加上meanCenters=pd.DataFrame(<your_output>)。如果您将其包含在主要代码片段中,那就更好了。 - vestland
1
谢谢,非常有道理!现在代码片段已经可以完全自己运行了。 - Chris Wilson
太好了!顺便问一下,你是手动将字典放在一行上的吗?还是在函数中找到了某些参数来实现这个功能? - vestland
1
我刚刚通过 json.dumps() 运行了它! - Chris Wilson
你会对一种侧重于数据本身的方法感兴趣吗?换句话说,它专注于数据而不一定是密苏里州。 - vestland
显示剩余2条评论
1个回答

5

我还没有找到一种直接展示像 密苏里州 这样地理区域的方法,但是你可以使用以下方式指定如何聚焦于你的数据:

fig.update_geos(fitbounds='locations')

这对于您的数据样本会得到如下结果:

enter image description here

因此,这种简单的方法对于包含更大的美国地图部分的大型数据集会更有意义。但是在这里非常好的一点是,您可以使用px.Line()构建您的图形,然后通过添加以下内容进行补充:

fig.add_traces(go.Scattergeo(lat=[41,36], lon=[-96,-89]

这些坐标恰好描绘了地图的轮廓,包括密苏里州,因此您会得到这个结果(标记设置为100%透明):

enter image description here

如果我理解您的意思正确的话,这就是您要寻找的东西吗? 也许从这个建议中最好的要点是,您可以使用px.express构建一个图形,使用fig.add_traces(go.Scattergeo())添加数据,然后使用fig.update_geos() 和不仅是 fig.update_layout() 编辑地理特征。

这是一个完整的代码片段,可重现第二张图:

import plotly.express as px
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 = px.line_geo(lat=meanCenters['lat'], lon=meanCenters['lng'])

fig.add_traces(go.Scattergeo(lat=[41,36], lon=[-96,-89],
                             mode = 'markers',
                             marker = dict(size = 2,color = 'rgba(0, 0, 0, 0)'),
                             name='Missouri'))

fig.update_geos(visible=True, resolution=50, scope="north america",
                fitbounds='locations',
                showcountries=True, countrycolor="Black",
                showsubunits=True, subunitcolor="grey")

fig.show()

1
这正是我所需要的!最终使用情况将具有不可预测的路径,因此这比手动输入状态要好得多。谢谢! - Chris Wilson
@ChrisWilson 没问题!我期待着在 [plotly] 标签下看到更多你的帖子。 - vestland
1
@vestland 对于 mapbox 函数,如 plotly.express.choropleth_mapboxupdate_geos() 不起作用。 - BetterCallMe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接