如何使用地图的绘图组件

相关空间:标签:地块、地图

介绍

本指南介绍了如何使用 Gradio 通过 gradio.Plot 组件在地图上绘制地理数据。 Gradio Plot 组件适用于 Matplotlib、Bokeh 和 Plotly。 Plotly 是我们将在本指南中使用的内容。 Plotly 允许开发人员使用他们的地理数据轻松创建各种地图。 看看这里的一些例子。

This guide explains how you can use Gradio to plot geographical data on a map using the gradio.Plot component. The Gradio Plot component works with Matplotlib, Bokeh and Plotly. Plotly is what we will be working with in this guide. Plotly allows developers to easily create all sorts of maps with their geographical data. Take a look here for some examples.

概述

我们将使用kaggle 上托管的纽约市 Airbnb 数据集。 我已将其作为数据集上传到 Hugging Face Hub,以便于使用和下载。 使用此数据,我们将在地图输出上绘制 Airbnb 位置,并允许根据价格和位置进行过滤。 下面是我们将要构建的演示。 ⚡️

We will be using the New York City Airbnb dataset, which is hosted on kaggle here. I've uploaded it to the Hugging Face Hub as a dataset here for easier use and download. Using this data we will plot Airbnb locations on a map output and allow filtering based on price and location. Below is the demo that we will be building. ⚡️

第 1 步 - 加载 CSV 数据 💾

让我们从从 Hugging Face Hub 加载 Airbnb NYC 数据开始。

Let's start by loading the Airbnb NYC data from the Hugging Face Hub.

from datasets import load_dataset

dataset = load_dataset("gradio/NYC-Airbnb-Open-Data", split="train")
df = dataset.to_pandas()

def filter_map(min_price, max_price, boroughs):
    new_df = df[(df['neighbourhood_group'].isin(boroughs)) & 
            (df['price'] > min_price) & (df['price'] < max_price)]
    names = new_df["name"].tolist()
    prices = new_df["price"].tolist()
    text_list = [(names[i], prices[i]) for i in range(0, len(names))]

在上面的代码中,我们首先将 csv 数据加载到 pandas 数据框中。 让我们首先定义一个函数,我们将用作 gradio 应用程序的预测函数。 此函数将接受最低价格和最高价格范围以及行政区列表以过滤生成的地图。 我们可以使用传入的值( min_pricemax_priceboroughs 列表)来过滤数据框并创建 new_df 。 接下来我们将创建每个 Airbnb 的名称和价格的 text_list 以用作地图上的标签。

In the code above, we first load the csv data into a pandas dataframe. Let's begin by defining a function that we will use as the prediction function for the gradio app. This function will accept the minimum price and maximum price range as well as the list of boroughs to filter the resulting map. We can use the passed in values (min_price, max_price, and list of boroughs) to filter the dataframe and create new_df. Next we will create text_list of the names and prices of each Airbnb to use as labels on the map.

第 2 步 - 地图图🌐

Plotly 使使用地图变得容易。 下面让我们看看如何创建地图图形。

Plotly makes it easy to work with maps. Let's take a look below how we can create a map figure.

import plotly.graph_objects as go

fig = go.Figure(go.Scattermapbox(
            customdata=text_list,
            lat=new_df['latitude'].tolist(),
            lon=new_df['longitude'].tolist(),
            mode='markers',
            marker=go.scattermapbox.Marker(
                size=6
            ),
            hoverinfo="text",
            hovertemplate='Name: %{customdata[0]}
Price: $%{customdata[1]}' )) fig.update_layout( mapbox_style="open-street-map", hovermode='closest', mapbox=dict( bearing=0, center=go.layout.mapbox.Center( lat=40.67, lon=-73.90 ), pitch=0, zoom=9 ), )

上面,我们通过将我们的纬度和经度列表传递给绘图标记,在 mapbox 上创建了一个散点图。 我们还传递了名称和价格的自定义数据,以便在我们悬停的每个标记上显示更多信息。 接下来我们使用 update_layout 指定其他地图设置,例如缩放和居中。

Above, we create a scatter plot on mapbox by passing it our list of latitudes and longitudes to plot markers. We also pass in our custom data of names and prices for additional info to appear on every marker we hover over. Next we use update_layout to specify other map settings such as zoom, and centering.

有关使用 Mapbox 和 Plotly 绘制散点图的更多信息,请参见此处

More info here on scatter plots using Mapbox and Plotly.

第 3 步 - Gradio 应用 ⚡️

我们将使用两个 gr.Number 组件和一个 gr.CheckboxGroup 来允许我们应用程序的用户指定价格范围和自治市镇位置。 然后我们将使用 gr.Plot 组件作为我们之前创建的 Plotly + Mapbox 地图的输出。

We will use two gr.Number components and a gr.CheckboxGroup to allow users of our app to specify price ranges and borough locations. We will then use the gr.Plot component as an output for our Plotly + Mapbox map we created earlier.

with gr.Blocks() as demo:
    with gr.Column():
        with gr.Row():
            min_price = gr.Number(value=250, label="Minimum Price")
            max_price = gr.Number(value=1000, label="Maximum Price")
        boroughs = gr.CheckboxGroup(choices=["Queens", "Brooklyn", "Manhattan", "Bronx", "Staten Island"], value=["Queens", "Brooklyn"], label="Select Boroughs:")
        btn = gr.Button(value="Update Filter")
        map = gr.Plot()
    demo.load(filter_map, [min_price, max_price, boroughs], map)
    btn.click(filter_map, [min_price, max_price, boroughs], map)

我们使用 gr.Columngr.Row 对这些组件进行布局,我们还将为首次加载演示时以及单击“更新过滤器”按钮时添加事件触发器,以触发地图使用我们的新过滤器进行更新。

We layout these components using the gr.Column and gr.Row and we'll also add event triggers for when the demo first loads and when our "Update Filter" button is clicked in order to trigger the map to update with our new filters.

完整的演示代码如下所示:

This is what the full demo code looks like:

import gradio as gr
import plotly.graph_objects as go
from datasets import load_dataset

dataset = load_dataset("gradio/NYC-Airbnb-Open-Data", split="train")
df = dataset.to_pandas()

def filter_map(min_price, max_price, boroughs):

    filtered_df = df[(df['neighbourhood_group'].isin(boroughs)) & 
          (df['price'] > min_price) & (df['price'] < max_price)]
    names = filtered_df["name"].tolist()
    prices = filtered_df["price"].tolist()
    text_list = [(names[i], prices[i]) for i in range(0, len(names))]
    fig = go.Figure(go.Scattermapbox(
            customdata=text_list,
            lat=filtered_df['latitude'].tolist(),
            lon=filtered_df['longitude'].tolist(),
            mode='markers',
            marker=go.scattermapbox.Marker(
                size=6
            ),
            hoverinfo="text",
            hovertemplate='Name: %{customdata[0]}
Price: $%{customdata[1]}' )) fig.update_layout( mapbox_style="open-street-map", hovermode='closest', mapbox=dict( bearing=0, center=go.layout.mapbox.Center( lat=40.67, lon=-73.90 ), pitch=0, zoom=9 ), ) return fig with gr.Blocks() as demo: with gr.Column(): with gr.Row(): min_price = gr.Number(value=250, label="Minimum Price") max_price = gr.Number(value=1000, label="Maximum Price") boroughs = gr.CheckboxGroup(choices=["Queens", "Brooklyn", "Manhattan", "Bronx", "Staten Island"], value=["Queens", "Brooklyn"], label="Select Boroughs:") btn = gr.Button(value="Update Filter") map = gr.Plot().style() demo.load(filter_map, [min_price, max_price, boroughs], map) btn.click(filter_map, [min_price, max_price, boroughs], map) demo.launch()

第 4 步 - 部署🤗

如果你运行上面的代码,你的应用程序将开始在本地运行。 你甚至可以通过将 share=True 参数传递给 launch 来获得一个临时的可共享链接。

If you run the code above, your app will start running locally. You can even get a temporary shareable link by passing the share=True parameter to launch.

但是,如果你想要永久部署解决方案怎么办? 让我们将 Gradio 应用程序部署到免费的 HuggingFace Spaces 平台。

But what if you want to a permanent deployment solution? Let's deploy our Gradio app to the free HuggingFace Spaces platform.

如果你以前没有使用过 Spaces,请在此处按照之前的指南进行操作。

If you haven't used Spaces before, follow the previous guide here.

结论🎉

大功告成! 这就是构建地图演示所需的全部代码。

And you're all done! That's all the code you need to build a map demo.

这是演示Map 演示完整代码的链接(在 Hugging Face Spaces 上)

Here's a link to the demo Map demo and complete code (on Hugging Face Spaces)