添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Folium 是一个基于 Leaflet 的 Python 库,用于将地理数据可视化为地图。Leaflet 是一个开源的交互式地图JavaScript库,而 Folium 则提供了一个简单的方式来将这些功能带到 Python 环境中。这对于数据科学家和分析师来说非常有用,因为他们可以在数据分析工作流程中轻松地创建、查看和分享地理空间数据。

folium 建立在 Python 生态系统的数据应用能力和 Leaflet.js 库的映射能力之上,在Python中操作数据,然后通过 folium 在 Leaflet 地图中可视化。folium 相比较于国内百度的 pyecharts 灵活性更强,能够自定义绘制区域,并且展现形式更加多样化。

这个开源库中有许多来自 OpenStreetMap、MapQuest Open、MapQuestOpen Aerial、Mapbox和Stamen 的内建地图元件,而且支持使用 Mapbox 或 Cloudmade 的 API 密钥来定制个性化的地图元件。Folium支持 GeoJSON 和 TopoJSON 两种文件格式的叠加,也可以将数据连接到这两种文件格式的叠加层,最后可使用 color-brewer 配色方案创建分布图。

Folium可以让你用 Python 强大生态系统来处理数据,然后用 Leaflet 地图来展示。Folium内置一些来自 OpenStreetMap、MapQuest Open、MapQuest Open Aerial、Mapbox和Stamen 的地图元件(tilesets),并且支持用 Mapbox 或者 Cloudmade API keys 来自定义地图元件。Folium支持 GeoJSON 和 TopJSON 叠加(overlays),绑定数据来创造一个分级统计图(Choropleth map)。但是,Folium库绘制热点图的时候,需要联网才可显示。

Folium 的主要特点包括:

  • 简单性 :Folium 提供了一个简单易用的接口,使得在 Python 中创建地图变得非常直接。
  • 功能丰富 :通过 Folium,用户可以添加标记、多边形、圆形、热力图等多种地图元素,还可以自定义样式来美化和定制地图。
  • 可扩展性 :由于基于 Leaflet,Folium 能够利用 Leaflet 社区丰富的插件来进一步增强地图的功能。
  • 集成性 :Folium 可以很好地与其他 Python 数据处理库(如 Pandas)集成,方便地从数据集中提取地理信息并将其可视化。
  • 导出能力 :Folium 可以导出为 HTML 文件,使得创建的地图可以在独立的网页中查看,也可以直接在 Jupyter Notebook 中进行预览。
  • 官方文档: https://python-visualization.github.io/folium/latest/user_guide.html

    1
    pip install folium

    demo 示例

    直接上代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import folium

    # 经纬度坐标
    latitude = 31.2623051474359
    longitude = 121.14525775641026

    # 创建一个以给定纬度和经度为中心的地图对象
    m = folium.Map(location=[latitude, longitude], zoom_start=18)

    for i in range(1, 5):
    for j in range(1, 5):
    cur_latitude = latitude + 0.0001 * i
    cur_longitude = longitude + 0.0001 * j
    folium.CircleMarker([cur_latitude, cur_longitude], radius=10, fill_color='red', tooltip=f'test {i} {j}').add_to(m)


    # 保存地图
    m.save("map-test.html")

    效果展示,打开该文件就是这个状态,十分方便友好

    https://python-visualization.github.io/folium/latest/user_guide/map.html

    folium.Map 是 Folium 的基本类,每个地图都需要创建这样一个实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import folium

    min_lon, max_lon = -45, -35
    min_lat, max_lat = -25, -15

    m = folium.Map(
    max_bounds=True,
    location=[-20, -40],
    zoom_start=6,
    min_lat=min_lat,
    max_lat=max_lat,
    min_lon=min_lon,
    max_lon=max_lon,
    )

    folium.CircleMarker([max_lat, min_lon], tooltip="Upper Left Corner").add_to(m)
    folium.CircleMarker([min_lat, min_lon], tooltip="Lower Left Corner").add_to(m)
    folium.CircleMarker([min_lat, max_lon], tooltip="Lower Right Corner").add_to(m)
    folium.CircleMarker([max_lat, max_lon], tooltip="Upper Right Corner").add_to(m)

    m

    可以通过参数设置初始位置、放缩倍数,限制区域等属性

    LayerControl

    可以向当前 map 添加或控制图层

    1
    2
    3
    4
    5
    6
    7
    8
    m = folium.Map(tiles=None)

    folium.TileLayer("OpenStreetMap").add_to(m)
    folium.TileLayer(show=False).add_to(m)

    folium.LayerControl().add_to(m)

    m

    手动展示标记

    1
    2
    3
    4
    5
    6
    7
    8
    m = folium.Map()

    fg = folium.FeatureGroup(name="Icon collection", show=False).add_to(m)
    folium.Marker(location=(0, 0)).add_to(fg)

    folium.LayerControl().add_to(m)

    m

    Popups

    可以向地图上的标记添加弹出介绍

    Simple popups

    弹出文字信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    import folium


    m = folium.Map([45, 0], zoom_start=4)

    folium.Marker([45, -30], popup="inline implicit popup").add_to(m)

    folium.CircleMarker(
    location=[45, -10],
    radius=25,
    fill=True,
    popup=folium.Popup("inline explicit Popup"),
    ).add_to(m)

    ls = folium.PolyLine(
    locations=[[43, 7], [43, 13], [47, 13], [47, 7], [43, 7]], color="red"
    )

    ls.add_child(folium.Popup("outline Popup on Polyline"))
    ls.add_to(m)

    gj = folium.GeoJson(
    data={"type": "Polygon", "coordinates": [[[27, 43], [33, 43], [33, 47], [27, 47]]]}
    )

    gj.add_child(folium.Popup("outline Popup on GeoJSON"))
    gj.add_to(m)

    m
    HTML in popup

    可以在弹出提示中加入 HTML 元素

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    mport branca

    m = folium.Map([43, -100], zoom_start=4)

    html = """
    <h1> This is a big popup</h1><br>
    With a few lines of code...
    <p>
    <code>
    from numpy import *<br>
    exp(-2*pi)
    </code>
    </p>
    """


    folium.Marker([30, -100], popup=html).add_to(m)

    m
    Iframe in popup

    也可以将 Iframe 添加进去

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # Let's create a Figure, with a map inside.
    f = branca.element.Figure()
    folium.Map([-25, 150], zoom_start=3).add_to(f)

    # Let's put the figure into an IFrame.
    iframe = branca.element.IFrame(width=500, height=300)
    f.add_to(iframe)

    # Let's put the IFrame in a Popup
    popup = folium.Popup(iframe, max_width=2650)

    # Let's create another map.
    m = folium.Map([43, -100], zoom_start=4)

    # Let's put the Popup on a marker, in the second map.
    folium.Marker([30, -100], popup=popup).add_to(m)

    # We get a map in a Popup. Not really useful, but powerful.
    m
    Vega chart in popup

    还可以加入 Vega 图表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import json

    import numpy as np
    import vincent

    multi_iter2 = {
    "x": np.random.uniform(size=(100,)),
    "y": np.random.uniform(size=(100,)),
    }
    scatter = vincent.Scatter(multi_iter2, iter_idx="x", height=100, width=200)
    data = json.loads(scatter.to_json())

    m = folium.Map([0, 0], zoom_start=1)
    marker = folium.Marker([0, 0]).add_to(m)
    popup = folium.Popup("Hello").add_to(marker)
    folium.Vega(data, width="100%", height="100%").add_to(popup)

    m
    Vega-Lite chart in popup

    更高级的 Vega 图表

    Vector Layers

    Circle and CircleMarker

    CircleMarker 以像素指定半径,而 Circle 以米指定。这意味着当你缩放时,CircleMarker 不会改变你屏幕上的大小,而 Circle 在地图上有一个固定的位置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    import folium

    m = folium.Map(location=[-27.5717, -48.6256], zoom_start=9)

    radius = 50
    folium.CircleMarker(
    location=[-27.55, -48.8],
    radius=radius,
    color="cornflowerblue",
    stroke=False,
    fill=True,
    fill_opacity=0.6,
    opacity=1,
    popup="{} pixels".format(radius),
    tooltip="I am in pixels",
    ).add_to(m)

    radius = 25
    folium.CircleMarker(
    location=[-27.35, -48.8],
    radius=radius,
    color="black",
    weight=3,
    fill=False,
    fill_opacity=0.6,
    opacity=1,
    ).add_to(m)

    radius = 10000
    folium.Circle(
    location=[-27.551667, -48.478889],
    radius=radius,
    color="black",
    weight=1,
    fill_opacity=0.6,
    opacity=1,
    fill_color="green",
    fill=False, # gets overridden by fill_color
    popup="{} meters".format(radius),
    tooltip="I am in meters",
    ).add_to(m)

    m
    PolyLine
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    # Coordinates are 15 points on the great circle from Boston to San Francisco.
    coordinates = [
    [42.3581, -71.0636],
    [42.82995815, -74.78991444],
    [43.17929819, -78.56603306],
    [43.40320216, -82.37774519],
    [43.49975489, -86.20965845],
    [43.46811941, -90.04569087],
    [43.30857071, -93.86961818],
    [43.02248456, -97.66563267],
    [42.61228259, -101.41886832],
    [42.08133868, -105.11585198],
    [41.4338549, -108.74485069],
    [40.67471747, -112.29609954],
    [39.8093434, -115.76190821],
    [38.84352776, -119.13665678],
    [37.7833, -122.4167],
    ]

    # Create the map and add the line
    m = folium.Map(location=[41.9, -97.3], zoom_start=4)

    folium.PolyLine(
    locations=coordinates,
    color="#FF0000",
    weight=5,
    tooltip="From Boston to San Francisco",
    ).add_to(m)

    m
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    m = folium.Map(location=[41.9, -97.3], zoom_start=4)

    folium.PolyLine(
    smooth_factor=50,
    locations=coordinates,
    color="grey",
    tooltip="Too much smoothing?",
    weight=5,
    ).add_to(m)

    m
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    lat = +38.89399
    lon = -77.03659
    zoom_start = 17

    m = folium.Map(location=[lat, lon], zoom_start=zoom_start)

    kw = {"color": "red", "fill": True, "radius": 20}

    folium.CircleMarker([38.89415, -77.03738], **kw).add_to(m)
    folium.CircleMarker([38.89415, -77.03578], **kw).add_to(m)


    locations = [
    [
    (38.893596444352134, -77.03814983367920),
    (38.893379333722040, -77.03792452812195),
    ],
    [
    (38.893379333722040, -77.03792452812195),
    (38.893162222428310, -77.03761339187622),
    ],
    [
    (38.893162222428310, -77.03761339187622),
    (38.893028615148424, -77.03731298446655),
    ],
    [
    (38.893028615148424, -77.03731298446655),
    (38.892920059048464, -77.03691601753235),
    ],
    [
    (38.892920059048464, -77.03691601753235),
    (38.892903358095296, -77.03637957572937),
    ],
    [
    (38.892903358095296, -77.03637957572937),
    (38.893011914220770, -77.03592896461487),
    ],
    [
    (38.893011914220770, -77.03592896461487),
    (38.893162222428310, -77.03549981117249),
    ],
    [
    (38.893162222428310, -77.03549981117249),
    (38.893404384982480, -77.03514575958252),
    ],
    [
    (38.893404384982480, -77.03514575958252),
    (38.893596444352134, -77.03496336936950),
    ],
    ]

    folium.PolyLine(
    locations=locations,
    color="orange",
    weight=8,
    opacity=1,
    smooth_factor=0,
    ).add_to(m)

    m
    Rectangle
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    m = folium.Map(location=[35.685, 139.76], zoom_start=15)

    kw = {
    "color": "blue",
    "line_cap": "round",
    "fill": True,
    "fill_color": "red",
    "weight": 5,
    "popup": "Tokyo, Japan",
    "tooltip": "<strong>Click me!</strong>",
    }

    folium.Rectangle(
    bounds=[[35.681, 139.766], [35.691, 139.776]],
    line_join="round",
    dash_array="5, 5",
    **kw,
    ).add_to(m)

    dx = 0.012
    folium.Rectangle(
    bounds=[[35.681, 139.766 - dx], [35.691, 139.776 - dx]],
    line_join="mitter",
    dash_array="5, 10",
    **kw,
    ).add_to(m)

    folium.Rectangle(
    bounds=[[35.681, 139.766 - 2 * dx], [35.691, 139.7762 - 2 * dx]],
    line_join="bevel",
    dash_array="15, 10, 5, 10, 15",
    **kw,
    ).add_to(m)

    m
    Polygon
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    m = folium.Map(location=[35.67, 139.78], zoom_start=13)

    locations = [
    [35.6762, 139.7795],
    [35.6718, 139.7831],
    [35.6767, 139.7868],
    [35.6795, 139.7824],
    [35.6787, 139.7791],
    ]

    folium.Polygon(
    locations=locations,
    color="blue",
    weight=6,
    fill_color="red",
    fill_opacity=0.5,
    fill=True,
    popup="Tokyo, Japan",
    tooltip="Click me!",
    ).add_to(m)

    m
    ColorLine
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import numpy as np

    x = np.linspace(0, 2 * np.pi, 300)

    lats = 20 * np.cos(x)
    lons = 20 * np.sin(x)
    colors = np.sin(5 * x)
    import folium

    m = folium.Map([0, 0], zoom_start=3)

    color_line = folium.ColorLine(
    positions=list(zip(lats, lons)),
    colors=colors,
    colormap=["y", "orange", "r"],
    weight=10,
    ).add_to(m)

    m

    更多功能参考: https://python-visualization.github.io/folium/latest/user_guide.html

  • https://python-visualization.github.io/folium/latest/user_guide.html
  • https://zhuanlan.zhihu.com/p/242268152
  •