向Choropleth地图添加下拉菜单以选择每个州并生成新的图表类型

3
我已经创建了一个区域地图,我想知道是否可以添加一个下拉列表,其中包含每个州的信息。当您选择下拉列表时,图形会更改为该州随时间获得的学士学位数量的折线图。
我的数据样本:
        year state statetotal ba_total
0     1984.0    AK      221.0    108.0
1     1985.0    AK      242.0    141.0
2     1984.0    NC      229.0    117.0
3     1985.0    NC      257.0    138.0
4     1984.0    MA      272.0    165.0
5     1985.0    MA      280.0    176.0
6     1984.0    NY      375.0    249.0
7     1985.0    NY      309.0    208.0

这是我迄今为止尝试过的内容:
for col in df.columns:
    df[col] = df[col].astype(str)

scl = [[0.0, 'rgb(242,240,247)'],[0.2, 'rgb(218,218,235)'],[0.4, 'rgb(188,189,220)'],\
            [0.6, 'rgb(158,154,200)'],[0.8, 'rgb(117,107,177)'],[1.0, 'rgb(84,39,143)']]

df['text'] = df['statename'] + '<br>' + \
    'Bachelor '+df['ba_total']+'<br>'+ \
    'Master '+df['ma_total']+'<br>'+ \
    'PhD '+df['phd_total']

# Years
years = list(df['year'].astype(float).astype(int).unique())

# make data
data = []

# Append data
for year in years:
    dataset_by_year = df[df['year'].astype(float).astype(int) == int(year)]

    data_dict = [ dict(
        type='choropleth',
        visible=True,
        colorscale = scl,
        autocolorscale = False,
        locations = dataset_by_year['state'],
        z = dataset_by_year['statetotal'].astype(float),
        locationmode = 'USA-states',
        text = dataset_by_year['text'],
        marker = dict(
            line = dict (
                color = 'rgb(255,255,255)',
                width = 2
            ) ),
        colorbar = dict(
            title = "Educ. Grads")
        ) ]
    data.append(data_dict[0])

# let's create the steps for the slider
steps = []
for i in range(len(data)):
    step = dict(method='restyle',
                args=['visible', [False] * len(data)],
                label='{}'.format(i + 1984))
    step['args'][1][i] = True
    steps.append(step)

sliders = [dict(active=0,
                pad={"t": 1},
                steps=steps)]    

# create the empty dropdown menu
updatemenus = list([dict(buttons=list()), 
                    dict(direction='down',
                         showactive=True)])

total_codes = len(df.state.unique()) + 1

for s, state in enumerate(df.state.unique()):
    # add a trace for each state
    data.append(dict(type='scatter',
                     x=[i for i in range(1984, 2016)],
                     y=[i for i in df.statetotal],
                     visible=False))

    # add each state to the dropdown    
    visible_traces = [False] * total_codes
    visible_traces[s + 1] = True
    updatemenus[0]['buttons'].append(dict(args=[{'visible': visible_traces}],
                                          label=state,
                                          method='update'))

# add a dropdown entry to reset the map    
updatemenus[0]['buttons'].append(dict(args=[{'visible': [True] + [False] *  (total_codes - 1)}],
                                      label='Map',
                                      method='update'))

layout = dict(title='Aggregated Number of Graduates in Education by State',
              updatemenus=updatemenus,
              geo=dict(scope='usa',
                       projection={'type': 'albers usa'}),
              sliders=sliders)

fig = dict(data=data, 
           layout=layout)

我创建的函数出现了一个与AttributeError相关的错误,但之前我成功生成了带有菜单的图形,不过生成的是50个菜单按钮而不是一个拥有50个选项的下拉菜单。我认为这些问题可以解决,但我的问题关键在于是否可能将图形类型组合起来?理想情况下,如果我点击阿拉斯加州,我想展示一条线图,显示观察时间段内完成的学士学位数量。这是可能的吗?
编辑代码:
我设法让下拉菜单正常工作,但它与滑块和地图结合得不太好。我不知道如何让滑块在单击下拉菜单中的项目时消失,也不知道如何防止地图覆盖在线图上方。
1个回答

5
您可以在Plotly在线获取所需的功能,但所有数据都需要在第一个图形呈现时加载。也许可以看一下Plotly的Dash,它可以实现动态加载数据。
为了获得显示轨迹的下拉菜单,您可以执行以下操作:
- 首先创建地图,然后为每个国家添加散点图,但只设置visible属性来显示地图。 - 创建下拉菜单,该菜单显示所选国家的散点图(通过将布尔数组传递给visible)。 - 添加一个菜单条目以再次显示地图。

enter image description here

enter image description here

import pandas as pd
import plotly

plotly.offline.init_notebook_mode()
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_us_ag_exports.csv')

# create the initial map
data = [dict(type='choropleth',
             locations = df['code'].astype(str),
             z=df['total exports'].astype(float),
             locationmode='USA-states', 
             visible=True)]

layout = dict(geo=dict(scope='usa',
                       projection={'type': 'albers usa'}))

# create the empty dropdown menu
updatemenus = list([dict(buttons=list()), 
                    dict(direction='down',
                         showactive=True)])

total_codes = len(df.code.unique()) + 1

for s, state in enumerate(df.code.unique()):
    # add a trace for each state
    data.append(dict(type='scatter',
                     x=[i for i in range(1980, 2016)],
                     y=[i + random.random() * 100 for i in range(1980, 2016)],
                     visible=False))

    # add each state to the dropdown    
    visible_traces = [False] * total_codes
    visible_traces[s + 1] = True
    updatemenus[0]['buttons'].append(dict(args=[{'visible': visible_traces}],
                                          label=state,
                                          method='update'))

# add a dropdown entry to reset the map    
updatemenus[0]['buttons'].append(dict(args=[{'visible': [True] + [False] *  (total_codes - 1)}],
                                      label='Map',
                                      method='update'))
layout['updatemenus'] = updatemenus

fig = dict(data=data, 
           layout=layout)
plotly.offline.iplot(fig)

这太棒了!你知道是否可以将它与滑块结合,以便滑块仅在地图上显示?(请参见编辑) - otteheng
1
@otteheng:很可能是的,您需要更新每个下拉菜单的“布局”,这可能会有点混乱,但应该可以工作。 - Maximilian Peters
我想我在查找layout中关闭slider的位置时遇到了困难。我可以为整个图表禁用slider,但无法单独为每个下拉菜单禁用它。 - otteheng
我正在向同事展示这段代码,以便他们可以使用另一个数据集来重现它,但它似乎不再按预期工作。快速浏览让我认为这与哪些项目可见或不可见有关。稍后会仔细查看。 - otteheng

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