【问题标题】:plotly.graph_objects Choropleth Map subplots with shared colorscaleplotly.graph_objects Choropleth 使用共享色标绘制子图
【发布时间】:2020-06-11 15:55:19
【问题描述】:

我是 python 和 plotly.graph_objects 的新手。我创建了一些类似于此处找到的示例的地图:United States Choropleth Map 我想将地图组合成一个具有通用色标的图形。我看过很多在子图上使用共享比例尺的人的例子,但他们使用的是不同的图形库。是否支持我想要的功能?如果是这样,它是如何完成的?

这是我正在使用的代码:

import plotly.graph_objects as go
import pandas as pd

df_shootings = pd.read_csv('https://raw.githubusercontent.com/washingtonpost/data-police-shootings/master/fatal-police-shootings-data.csv')

state_count = df_shootings.groupby(['state', 'race']).size().reset_index(name='total')

races = pd.DataFrame({'W': 'White, non-Hispanic',
    'B': 'Black, non-Hispanic',
    'A': 'Asian',
    'N': 'Native American',
    'H': 'Hispanic'}, index=[0])

for race in races:
    result = state_count[['state', 'total']][state_count.race == race]
    fig = go.Figure(data=go.Choropleth(
        locations=result.state,
        z = result.total,
        locationmode = 'USA-states', # set of locations match entries in `locations`
        marker_line_color='white',
        colorbar_title = "Shooting deaths",
    ))

    fig.update_layout(
        title_text = races[race][0],
        geo_scope='usa', # limite map scope to USA
    )
    fig.data[0].hovertemplate =  'State: %{location}<br>Shooting deaths: %{z:.2f}<extra></extra>'
    fig.show()

这是我想要得到的:

现在我得到了具有自己颜色比例的单独地图,每张地图都不同。

【问题讨论】:

    标签: python choropleth plotly.graph-objects


    【解决方案1】:

    我正在做一个类似的项目,并做到了这一点See picture 找不到如何命名子图的方法

    import plotly.graph_objects as go
    import pandas as pd
    
    df_shootings = pd.read_csv('https://raw.githubusercontent.com/washingtonpost/data-police-shootings/master/fatal-police-shootings-data.csv')
    
    state_count = df_shootings.groupby(['state', 'race']).size().reset_index(name='total')
    
    races = pd.DataFrame({'W': 'White, non-Hispanic',
        'B': 'Black, non-Hispanic',
        'A': 'Asian',
        'N': 'Native American',
        'H': 'Hispanic'}, index=[0])
    races
    fig = go.Figure()
    layout = dict(
        title_text = "Fatal Police Shootings Data",
        geo_scope='usa',
    )
    
    for index, race in enumerate(races):
        result = state_count[['state', 'total']][state_count.race == race]
        geo_key = 'geo'+str(index+1) if index != 0 else 'geo'  
        fig.add_trace(
            go.Choropleth(
                locations=result.state,
                z = result.total,
                locationmode = 'USA-states', # set of locations match entries in `locations`
                marker_line_color='white',
                colorbar_title = "Shooting deaths",
                geo=geo_key,
                name=races[race].values[0],
                coloraxis = 'coloraxis',
            )
        )
        
        layout[geo_key] = dict(
            scope = 'usa',
            domain = dict( x = [], y = [] ),
        )
    
    layout
    z = 0
    COLS = 3
    ROWS = 2
    for y in reversed(range(ROWS)):
        for x in range(COLS):
            geo_key = 'geo'+str(z+1) if z != 0 else 'geo'
            layout[geo_key]['domain']['x'] = [float(x)/float(COLS), float(x+1)/float(COLS)]
            layout[geo_key]['domain']['y'] = [float(y)/float(ROWS), float(y+1)/float(ROWS)]
            z=z+1
            if z > 4:
                break
                
    fig.update_layout(layout)   
    fig.show()
    

    【讨论】:

    • 欢迎来到 Stack Overflow。感谢您回答一个较老的问题。虽然有时只有代码的答案就足够了,但我认为如果您可以为您的解决方案提供额外的上下文和解释,那就太好了。 – 从这里开始,请使用tour,也可以参考How do I write a good answer?
    【解决方案2】:

    我刚刚为我自己的项目解决了这个问题。我重写了您的代码并用 cmets 将其拆分。

    这里没有变化,除了添加几个通用包和一些代码的位置。

    import plotly.graph_objects as go
    from plotly.subplots import make_subplots
    import pandas as pd
    import numpy as np
    
    df_shootings = pd.read_csv('https://raw.githubusercontent.com/washingtonpost/data-police-shootings/master/fatal-police-shootings-data.csv')
    
    state_count = df_shootings.groupby(['state', 'race']).size().reset_index(name='total')
    
    races = pd.DataFrame({'W': 'White, non-Hispanic',
        'B': 'Black, non-Hispanic',
        'A': 'Asian',
        'N': 'Native American',
        'H': 'Hispanic'}, index=[0])
    

    声明一个子图。您需要指定行数和列数,您需要准备子图以专门接收等值线,我们将使用您的 races 数据框来声明您的子图标题。

    rows = 2
    cols = 3
    fig = make_subplots(
        rows=rows, cols=cols,
        specs = [[{'type': 'choropleth'} for c in np.arange(cols)] for r in np.arange(rows)],
        subplot_titles = list(races.loc[0,:]))
    

    我使用enumerate 来计算每个子图的正确行和列。我不知道这是否是pythonic。当我们经过races 时,值i 只是从0 开始计数。每次通过循环,我们都会将跟踪添加到适当的行和列。为了确保我们对每个子图使用相同的色标,我们将 zminzmax 分别设置为 0 和最大值 state_count['total']rowcol 的计算使用来自 enumerate 的计数来确定我们将其绘制在哪一行和哪一列中。

    for i, race in enumerate(races):
        result = state_count[['state', 'total']][state_count.race == race]
        fig.add_trace(go.Choropleth(
            locations=result.state,
            z = result.total,
            locationmode = 'USA-states', # set of locations match entries in `locations`
            marker_line_color='white',
            zmin = 0,
            zmax = max(state_count['total']),
            colorbar_title = "Shooting deaths",
        ), row = i//cols+1, col = i%cols+1)
    

    我为整个人物编了一个我认为合适的标题。下一行对我来说是个绝招,但这就是将每个子图设置为美国的图而不是整个世界的默认地图的原因。没有它,只有第一个子图会使用美国地图。我会给你我对发生的事情的最好理解,我找不到或想出更好的解决方案。基本上,每个子图都有一个有点的位置,依次命名为geogeo2geo3geo4 等。每个子图都必须将其范围设置为usa。 'Magic' 下划线不起作用,所以我必须组合一个 **kwargs(关键字参数),它等同于 geo_scope = 'usa', geo2_scope = 'usa', geo3_scope = 'usa', geo4_scope = 'usa', geo5_scope = 'usa'。诚然,打字还不错,但在我的项目中,我有 50 个子图,所以我对其进行了编码。基本上我做了一本字典,然后用**将它转换为kwargs。事实上,关键字参数列表以 geo 而不是 geo0 甚至 geo1 开头,这就是该行如此复杂的原因。

    fig.update_layout(
        title_text = 'Shooting Deaths by Race',
        **{'geo' + str(i) + '_scope': 'usa' for i in [''] + np.arange(2,rows*cols+1).tolist()},
        )
    
    for index, trace in enumerate(fig.data):
        fig.data[index].hovertemplate = 'State: %{location}<br>Shooting deaths: %{z:.2f}
    <extra></extra>'
    fig.show()
    

    结果如下: Shooting Deaths by Race

    【讨论】:

      猜你喜欢
      • 2022-01-06
      • 2015-02-02
      • 2019-07-13
      • 2021-04-21
      • 2014-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      相关资源
      最近更新 更多