Python绘制地图神器folium的新人入门指南

编辑: admin 分类: python 发布时间: 2021-12-24 来源:互联网
目录
  • 一、简介
  • 二、安装方法
  • 三、主要功能
    • 3.1 各级别地图
      •  3.1.1 世界地图
    • 3.1.2 国家地图
      • 3.1.3 市级地图
    • 3.2 地图形式
      • 3.3 在地图上标记
        • 3.3.1 普通标记
        • 3.3.2 点击获取经纬度
        • 3.3.3 动态放置标记
      • 3.4 热力图绘制
        • 3.5 密度地图绘制
          • 3.6 自定义地图区域
            • 3.6.1 只绘制边界,不添加数据
            • 3.6.2 绘制边界,添加数据
        • 四、竞品对比与优劣势
          • 五、参考资料

            一、简介

            想通过 Python 绘制精美的地图?想在地图上自由的设置各种参数?想获得灵活的交互体验?这里就有一款Python 神包满足你:folium

            folium 建立在 Python 生态系统的数据应用能力和 Leaflet.js 库的映射能力之上,在Python中操作数据,然后通过 folium 在 Leaflet 地图中可视化。

            folium 相比较于国内百度的 pyecharts 灵活性更强,能够自定义绘制区域,并且展现形式更加多样化。

            附:官方文档,官方示例,本文 notebook ,完整代码及数据。

            二、安装方法

            按照官方的教程即可,如果安装了 conda ,可以直接

            conda install -c conda-forge folium

            没有安装的话就使用

            python3 -m pip install folium

            三、主要功能

            3.1 各级别地图

            folium 显示地图的类为 folium.Map,类的声明如下

            class folium.folium.Map(location=None, width='100%', height='100%', left='0%', top='0%', position='relative', tiles='OpenStreetMap', attr=None, min_zoom=0, max_zoom=18, zoom_start=10, min_lat=-90, max_lat=90, min_lon=-180, max_lon=180, max_bounds=False, crs='EPSG3857', control_scale=False, prefer_canvas=False, no_touch=False, disable_3d=False, png_enabled=False, zoom_control=True, **kwargs)
            

            讲几个重要的参数

            • location 经纬度,list 或者 tuple 格式,顺序为 latitude, longitude
            • zoom_start 缩放值,默认为 10,值越大比例尺越小,地图放大级别越大
            • tiles 显示样式,默认*‘OpenStreetMap'*,也就是开启街道显示
            • crs 地理坐标参考系统,默认为"EPSG3857"

             3.1.1 世界地图

            import folium
            
            print(folium.__version__)
            
            # define the world map
            world_map = folium.Map()
            # display world map
            world_map

            image-20200309205212588

            3.1.2 国家地图

            # define the national map
            national_map = folium.Map(location=[35.3, 100.6], zoom_start=4)
            # display national map
            national_map

            image-20200310014116766

            3.1.3 市级地图

            其实改变地图显示就是改变显示的经纬度和缩放比例,省级、市级、县级用法雷同,这里举一个市级的例子为例,如北京市:

            # define the city map
            city_map = folium.Map(location=[39.93, 116.40], zoom_start=10)
            # display city map
            city_map

            image-20200309205918570

            显示效果确实是不如百度的😓。

            3.2 地图形式

            除了上述正常的地图显示外,folium 还提供了非常丰富的多样化显示,控制显示效果的变量是tiles,样式有OpenStreetMap, Stamen Terrain, Stamen Toner, Mapbox Bright, Mapbox Control Room等等,这里挑选几个比较常见的

            # define the city map,tiles='Stamen Toner'
            city_map = folium.Map(location=[39.93, 116.40], zoom_start=10, tiles='Stamen Toner')
            # display city map
            city_map
            
            # define the city map, tiles='Stamen Terrain'
            city_map = folium.Map(location=[39.93, 116.40], zoom_start=10, tiles='Stamen Terrain')
            # display city map
            city_map
            

            Stamen Toner & Stamen Terrain

            3.3 在地图上标记

            3.3.1 普通标记

            添加普通标记用 Marker

            这里可以选择标记的图案。

            bj_map = folium.Map(location=[39.93, 115.40], zoom_start=12, tiles='Stamen Terrain')
            
            folium.Marker(
                location=[39.95, 115.33],
                popup='Mt. Hood Meadows',
                icon=folium.Icon(icon='cloud')
            ).add_to(bj_map)
            
            folium.Marker(
                location=[39.96, 115.32],
                popup='Timberline Lodge',
                icon=folium.Icon(color='green')
            ).add_to(bj_map)
            
            folium.Marker(
                location=[39.93, 115.34],
                popup='Some Other Location',
                icon=folium.Icon(color='red', icon='info-sign')
            ).add_to(bj_map)
            
            bj_map
            

            image-20200309212826073

            添加圆形标记用 Circle 以及 CircleMarker

            bj_map = folium.Map(location=[39.93, 116.40], zoom_start=12, tiles='Stamen Toner')
            
            folium.Circle(
                radius=200,
                location=[39.92, 116.43],
                popup='The Waterfront',
                color='crimson',
                fill=False,
            ).add_to(bj_map)
            
            folium.CircleMarker(
                location=[39.93, 116.38],
                radius=50,
                popup='Laurelhurst Park',
                color='#3186cc',
                fill=True,
                fill_color='#3186cc'
            ).add_to(bj_map)
            
            bj_map
            

            image-20200309212843415

            3.3.2 点击获取经纬度

            m = folium.Map(location=[46.1991, -122.1889],tiles='Stamen Terrain',zoom_start=13)
            
            m.add_child(folium.LatLngPopup())
            
            m

            通过点击鼠标便可以获取点击出的经纬度。

            Kapture 2020-03-09 at 22.00.40

            3.3.3 动态放置标记

            m = folium.Map(
                location=[46.8527, -121.7649],
                tiles='Stamen Terrain',
                zoom_start=13
            )
            
            folium.Marker(
                [46.8354, -121.7325],
                popup='Camp Muir'
            ).add_to(m)
            
            m.add_child(folium.ClickForMarker(popup='Waypoint'))
            
            m
            

            Kapture 2020-03-11 at 10.39.44

            3.4 热力图绘制

            因为没有实际的经纬度坐标数据,所以这里只能模拟一些位置出来,另外每个位置还需要一个数值作为热力值。

            # generated data
            import numpy as np
            data = (
                np.random.normal(size=(100, 3)) *
                np.array([[0.1, 0.1, 0.1]]) +
                np.array([[40, 116.5, 1]])
            ).tolist()
            data[:3]
            

            数据分布

            [[40.04666663299843, 116.59569796477264, 0.9667425547098781],
             [39.86836537517533, 116.28201445195315, 0.8708549157348728],
             [40.08123232852134, 116.56884585184197, 0.9104952244371285]]
            

            绘制热力图

            # HeatMap
            from folium.plugins import HeatMap
            m = folium.Map([39.93, 116.38], tiles='stamentoner', zoom_start=6)
            HeatMap(data).add_to(m)
            # m.save(os.path.join('results', 'Heatmap.html'))
            m
            

            image-20200310231553948

            3.5 密度地图绘制

            folium 不仅可以绘制热力图,还可以绘制密度地图,按照经纬度进行举例聚类,然后在地图中显示。

            from folium.plugins import MarkerCluster
            
            m = folium.Map([39.93, 116.38], tiles='stamentoner', zoom_start=10)
            
            # create a mark cluster object
            marker_cluster = MarkerCluster().add_to(m)
            
            # add data point to the mark cluster
            for lat, lng, label in data:
                folium.Marker(
                    location=[lat, lng],
                    icon=None,
                    popup=label,
                ).add_to(marker_cluster)
            
            # add marker_cluster to map
            m.add_child(marker_cluster)
            

            image-20200310232519456

            3.6 自定义地图区域

            folium 一个非常有优势的功能就是自定义区域的绘制了,只要有区域的边界数据,就可以在地图中以多种多样的形式展现出来,这里以 folium 官方的美国地图为例,源数据是一个 .json 文件,里面包含了各个地区(美国各州)的特征(包括边界经纬度列表、简称等),源数据传送门,其数据格式如下:

            image-20200310233211972

            3.6.1 只绘制边界,不添加数据

            如果只要求绘制边界,而不显示边界区域的相关信息,那么这个是比较容易的,代码如下

            import json
            import requests
            
            # read us-states border 
            with open("us-states.json") as f:
                us_states = json.load(f)
            
            us_map = folium.Map(location=[35.3, -97.6], zoom_start=4)
            folium.GeoJson(
                us_states,
                style_function=lambda feature: {
                    'fillColor': '#ffff00',
                    'color': 'black',
                    'weight': 2,
                    'dashArray': '5, 5'
                }
            ).add_to(us_map)
            
            #display map
            us_map
            

            image-20200310233644765

            3.6.2 绘制边界,添加数据

            当需要在各个区域填充数据的时候,这个稍微麻烦点,不仅需要各个区域的边界数据,还需要各个区域的显示信息,这里同样也使用官方的美国各州的边界数据为例:

            import geopandas as gpd
            import pandas as pd
            import folium, branca
            
            states = gpd.GeoDataFrame.from_features(us_states, crs=fiona.crs.from_epsg(4326))
            states.head()
            

            image-20200311001008073

            我们再把收入等数据连接到上表中

            abbrs = pd.read_json(open("abbrs.json"))
            statesmerge = states.merge(abbrs,how='left', left_on='name', right_on='name')
            statesmerge['geometry']=statesmerge.geometry.simplify(.05)
            income = pd.read_csv("income.csv", dtype={"fips":str})
            income['income-2015']=pd.to_numeric(income['income-2015'], errors='coerce')
            income.groupby(by="state")[['state','income-2015']].median().head()
            statesmerge['medianincome']=statesmerge.merge(income.groupby(by="state")[['state','income-2015']].median(), how='left', left_on='alpha-2', right_on='state')['income-2015']
            statesmerge['change']=statesmerge.merge(income.groupby(by="state")[['state','change']].median(), how='left', left_on='alpha-2', right_on='state')['change']
            statesmerge.head()
            

            image-20200311003029494

            最终绘制出的来的地图如下:

            00831rSTly1gcpr4az8hdg30re0ggqv8

            除此之外,还有很多非常有趣的功能,这里就不一一列举了,感兴趣的可以参考官方的文档。

            四、竞品对比与优劣势

            国内的竞品为百度的 pyecharts,和 folium 一样都可以实现普通的地图绘制功能,但是具体使用还有较大的区别,具体如下表

            功能 pyecharts folium 备注 世界地图 可以 可以 中文显示 可以 部分可以 folium地图中标尺、文字不能正常显示,但是嵌入地图中的中文可以正常显示 交互性 好 好 区(县)级地图 可以 可以 folium需要区(县)边界数据 市级地图 可以 可以 folium需要市边界数据 收费 自定义区域需要购买百度ak 自定义区域功能免费 灵活性 好 好 省级地图 可以 可以 folium需要省边界数据 美观度 好 较好 自定义区域 部分可以 可以 pyecharts需要百度 ak,folium免费

            五、参考资料

            [1] https://www.zhihu.com/question/33783546

            [2] https://pypi.org/project/folium/

            [3] https://nbviewer.jupyter.org/github/python-visualization/folium/tree/master/examples/

            到此这篇关于Python绘制地图神器folium的文章就介绍到这了,更多相关Python绘制地图folium内容请搜索hwidc以前的文章或继续浏览下面的相关文章希望大家以后多多支持hwidc!

            【本文由:http://www.yidunidc.com/krzq.html 复制请保留原URL】