【问题标题】:Animate a Plotly map with a sliding date bar使用滑动日期栏为 Plotly 地图制作动画
【发布时间】:2020-02-23 20:07:08
【问题描述】:

我正在努力将我编写的这段代码(构建 static 热图)转换为带有日期滑块的 动画 版本。

import pandas as pd
import plotly.graph_objects as go

...

fig = go.Figure(go.Densitymapbox(lat=df_heat['lat'], lon=df_heat['lon'], z=df_heat['count'],
                                 radius=10,))
fig.update_layout(mapbox_style="carto-positron", mapbox_zoom=10, mapbox_center = {"lat": 40.7831, "lon": -73.9712},)

fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()

上面的代码成功地将如下所示的 Pandas DataFrame df_heat 转换为 Plotly heatmap

    lat         lon         count
0   -62.884215  39.440236   1
1   -62.834226  39.408072   1
2   -62.811707  39.380462   1
3   -62.744564  39.489112   1
...

静态热图输出:

df_heat 本身只是以下 DataFrame 的聚合视图,其中还包括一个日期。

    date        lat         lon         count
0   2018-07-29  40.691828   -73.944609  1
1   2018-07-29  40.693601   -73.945092  1
2   2018-07-29  40.696132   -73.945178  1
3   2018-07-29  40.692726   -73.945532  1

我的问题是,如何将这个 DataFrame with dates 转换为 animated 绘图地图,例如 herehere 和 @987654324 @,它以日期滑块为过滤器。

用于测试的虚拟数据:

df = pd.DataFrame({'datetime': {0: '2018-09-29 00:00:00', 1: '2018-07-28 00:00:00', 2: '2018-07-29 00:00:00', 3: '2018-07-29 00:00:00', 4: '2018-08-01 00:00:00', 5: '2018-08-01 00:00:00', 6: '2018-08-01 00:00:00', 7: '2018-08-05 00:00:00', 8: '2018-09-06 00:00:00', 9: '2018-09-07 00:00:00', 10: '2018-09-07 00:00:00', 11: '2018-09-08 00:00:00', 12: '2018-09-08 00:00:00', 13: '2018-09-08 00:00:00', 14: '2018-10-08 00:00:00', 15: '2018-10-10 00:00:00', 16: '2018-10-10 00:00:00', 17: '2018-10-11 00:00:00', 18: '2018-10-11 00:00:00', 19: '2018-10-11 00:00:00'},
 'lat': {0: 40.6908284, 1: 40.693601, 2: 40.6951317, 3: 40.6967261, 4: 40.697593, 5: 40.6987141, 6: 40.7186497, 7: 40.7187772, 8: 40.7196151, 9: 40.7196865, 10: 40.7187408, 11: 40.7189716, 12: 40.7214273, 13: 40.7226571, 14: 40.7236955, 15: 40.7247207, 16: 40.7221074, 17: 40.7445859, 18: 40.7476252, 19: 40.7476451},
 'lon': {0: -73.9336094, 1: -73.9350917, 2: -73.9351778, 3: -73.9355315, 4: -73.9366737, 5: -73.9393797, 6: -74.0011939, 7: -74.0010918, 8: -73.9887851, 9: -74.0035125, 10: -74.0250842, 11: -74.0299202, 12: -74.029886, 13: -74.027542, 14: -74.0290157, 15: -74.0291541, 16: -74.0220728, 17: -73.9442636, 18: -73.9641326, 19: -73.9533039},
 'count': {0: 1, 1: 2, 2: 5, 3: 1, 4: 6, 5: 1, 6: 3, 7: 2, 8: 1, 9: 7, 10: 3, 11: 3, 12: 1, 13: 2, 14: 1, 15: 1, 16: 2, 17: 1, 18: 1, 19: 1}})

【问题讨论】:

    标签: python python-3.x pandas animation plotly


    【解决方案1】:

    我做了一些更改并将时间线动画添加到您的代码中。 与 Teoretic 的解决方案类似,我也使用了 plotly.express,它使事情变得更短。

    实时示例 http://www.erangrinberg.de/plotly/map-animation.html

    import pandas as pd
    import plotly.express as px
    
    df = pd.DataFrame({'Date': {0: '2018-09-29 00:00:00', 1: '2018-07-28 00:00:00', 2: '2018-07-29 00:00:00', 3: '2018-07-29 00:00:00', 4: '2018-08-01 00:00:00', 5: '2018-08-01 00:00:00', 6: '2018-08-01 00:00:00', 7: '2018-08-05 00:00:00', 8: '2018-09-06 00:00:00', 9: '2018-09-07 00:00:00', 10: '2018-09-07 00:00:00', 11: '2018-09-08 00:00:00', 12: '2018-09-08 00:00:00', 13: '2018-09-08 00:00:00', 14: '2018-10-08 00:00:00', 15: '2018-10-10 00:00:00', 16: '2018-10-10 00:00:00', 17: '2018-10-11 00:00:00', 18: '2018-10-11 00:00:00', 19: '2018-10-11 00:00:00'},
                      'lat': {0: 40.6908284, 1: 40.693601, 2: 40.6951317, 3: 40.6967261, 4: 40.697593, 5: 40.6987141, 6: 40.7186497, 7: 40.7187772, 8: 40.7196151, 9: 40.7196865, 10: 40.7187408, 11: 40.7189716, 12: 40.7214273, 13: 40.7226571, 14: 40.7236955, 15: 40.7247207, 16: 40.7221074, 17: 40.7445859, 18: 40.7476252, 19: 40.7476451},
                      'lon': {0: -73.9336094, 1: -73.9350917, 2: -73.9351778, 3: -73.9355315, 4: -73.9366737, 5: -73.9393797, 6: -74.0011939, 7: -74.0010918, 8: -73.9887851, 9: -74.0035125, 10: -74.0250842, 11: -74.0299202, 12: -74.029886, 13: -74.027542, 14: -74.0290157, 15: -74.0291541, 16: -74.0220728, 17: -73.9442636, 18: -73.9641326, 19: -73.9533039},
                      'count': {0: 1, 1: 2, 2: 5, 3: 1, 4: 6, 5: 1, 6: 3, 7: 2, 8: 1, 9: 7, 10: 3, 11: 3, 12: 1, 13: 2, 14: 1, 15: 1, 16: 2, 17: 1, 18: 1, 19: 1}})
    
    fig = px.density_mapbox(df, lat=df['lat'], 
                                lon=df['lon'], 
                                z=df['count'],
                                radius=10,
                                animation_frame="Date"
                                    )
    fig.update_layout(mapbox_style="carto-positron", mapbox_zoom=10, mapbox_center = {"lat": 40.7831, "lon": -73.9712},)
    fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
    
    fig.layout.updatemenus[0].buttons[0].args[1]["frame"]["duration"] = 600
    fig.layout.updatemenus[0].buttons[0].args[1]["transition"]["duration"] = 600
    fig.layout.coloraxis.showscale = True   
    fig.layout.sliders[0].pad.t = 10
    fig.layout.updatemenus[0].pad.t= 10             
    
    fig.show()
    

    很高兴看到最终结果, 或者您可以共享数据集源。

    【讨论】:

      【解决方案2】:

      您可以使用plotly.express中的scatter_geo绘图来获得交互式图表。
      它不会生成热图,但它可以在您的图表上制作点。

      带有您的虚拟数据的示例代码:

      import pandas as pd
      import plotly.express as px
      
      df = pd.DataFrame({'datetime': {0: '2018-09-29 00:00:00', 1: '2018-07-28 00:00:00', 2: '2018-07-29 00:00:00', 3: '2018-07-29 00:00:00', 4: '2018-08-01 00:00:00', 5: '2018-08-01 00:00:00', 6: '2018-08-01 00:00:00', 7: '2018-08-05 00:00:00', 8: '2018-09-06 00:00:00', 9: '2018-09-07 00:00:00', 10: '2018-09-07 00:00:00', 11: '2018-09-08 00:00:00', 12: '2018-09-08 00:00:00', 13: '2018-09-08 00:00:00', 14: '2018-10-08 00:00:00', 15: '2018-10-10 00:00:00', 16: '2018-10-10 00:00:00', 17: '2018-10-11 00:00:00', 18: '2018-10-11 00:00:00', 19: '2018-10-11 00:00:00'},
       'lat': {0: 40.6908284, 1: 40.693601, 2: 40.6951317, 3: 40.6967261, 4: 40.697593, 5: 40.6987141, 6: 40.7186497, 7: 40.7187772, 8: 40.7196151, 9: 40.7196865, 10: 40.7187408, 11: 40.7189716, 12: 40.7214273, 13: 40.7226571, 14: 40.7236955, 15: 40.7247207, 16: 40.7221074, 17: 40.7445859, 18: 40.7476252, 19: 40.7476451},
       'lon': {0: -73.9336094, 1: -73.9350917, 2: -73.9351778, 3: -73.9355315, 4: -73.9366737, 5: -73.9393797, 6: -74.0011939, 7: -74.0010918, 8: -73.9887851, 9: -74.0035125, 10: -74.0250842, 11: -74.0299202, 12: -74.029886, 13: -74.027542, 14: -74.0290157, 15: -74.0291541, 16: -74.0220728, 17: -73.9442636, 18: -73.9641326, 19: -73.9533039},
       'count': {0: 1, 1: 2, 2: 5, 3: 1, 4: 6, 5: 1, 6: 3, 7: 2, 8: 1, 9: 7, 10: 3, 11: 3, 12: 1, 13: 2, 14: 1, 15: 1, 16: 2, 17: 1, 18: 1, 19: 1}})
      fig = px.scatter_geo(df, 
                           lat='lat', 
                           lon='lon', 
                           scope='usa',
                           color="count", 
                           size='count',
                           projection="albers usa", 
                           animation_frame="datetime", 
                           title='Your title')
      fig.update(layout_coloraxis_showscale=False)
      fig.show()
      

      您也可以查看this kaggle notebook 了解更多使用此图表的示例。

      【讨论】:

      • 非常感谢您的帮助,这看起来很有潜力,但现在我的心已放在热图上。但是,如果事实证明热图过于复杂,这可能是一个不错的选择。你知道是否可以将scope 更改为不那么抽象的东西?例如,专注于我在问题中链接的城市。谢谢!
      • @Ian,你有没有得到带有时间滑块的热图工作?我正在追求一个非常相似的可视化,如果没有必要,我希望不必重新发明轮子。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      • 2020-11-02
      • 2020-07-25
      • 2019-08-06
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多