资讯动态

Gradio + Plotly 交互地图实战:用 gr.Plot 构建纽约 Airbnb 房源筛选应用

发布时间:2026/9/9 23:25:59 来源:尧图企业网站定制
Gradio Plotly 交互地图实战用 gr.Plot 构建纽约 Airbnb 房源筛选应用【免费下载链接】gradioBuild and share delightful machine learning apps, all in Python. Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/gr/gradio导读本文以仓库中的 map_airbnb 演示 为主体讲解如何用 Gradio 的gr.Plot组件承载 Plotly 的Scattermapbox散点地图并配合gr.Number、gr.CheckboxGroup、gr.Button实现按价格区间 按行政区联动过滤 Airbnb 房源的可交互 Web 应用。读完本文你将掌握从 Hugging Face Datasets 加载真实表格数据、用 pandas 做多条件筛选、用 Plotly 配置带 hover 详情的气泡地图以及在gr.Blocks中通过demo.load与按钮click事件驱动图表刷新的完整链路。一、演示功能与定位仓库中 demo/map_airbnb/DESCRIPTION.md 用一句话点明了该 demo 的核心目标Display an interactive map of AirBnB locations with Plotly. Data is hosted on HuggingFace Datasets.即用 Plotly 渲染 Airbnb 房源的交互式地图数据托管在 Hugging Face Datasets 上。落实到具体代码上它实现了如下三层能力数据接入通过datasets.load_dataset拉取纽约市 Airbnb 开放数据并转为 pandas DataFrame交互过滤前端输入最低价、最高价和行政区集合后端对 DataFrame 做布尔筛选重新生成地图地图展示以gr.Plot为输出组件承载 Plotly Figure无需自行编写任何前端 JavaScript。这与仓库中官方教程 plot-component-for-maps 指南 所述主题一致——Gradio 的gr.Plot组件本身支持 Matplotlib、Bokeh、Plotly、Altair 四类图见 plot.py本例选用的正是 Plotly。二、运行前准备与启动方式demo 目录结构非常简单仅包含三个文件run.py完整应用代码requirements.txt第三方依赖DESCRIPTION.md功能说明。其中 requirements.txt 内容为plotly datasetsplotly用于构建Scattermapbox地图对象datasets用于从 Hugging Face Hub 加载数据。启动前需确保当前 Python 环境已安装 gradio 本身以及上述两个依赖随后在仓库根目录执行pip install plotly datasets python demo/map_airbnb/run.py两点运行前提需要留意由代码行为可推断需要联网首次启动时load_dataset会从 Hugging Face Hub 下载gradio/NYC-Airbnb-Open-Data数据集之后由datasets库本地缓存离线重启时不再重复下载依赖首次调用加载from datasets import load_dataset属于模块顶层导入若当前环境未安装该库应用会在启动阶段直接报ImportError。三、数据接入从 Hugging Face Datasets 读取并转 DataFrameimport gradio as gr import plotly.graph_objects as go from datasets import load_dataset dataset load_dataset(gradio/NYC-Airbnb-Open-Data, splittrain) df dataset.to_pandas()代码在模块顶层一次性完成数据加载从数据集gradio/NYC-Airbnb-Open-Data的train分片读取数据再调用to_pandas()将 Arrow Table 转换为 pandas DataFrame后续的过滤、取列都基于df完成。从后面filter_map对列名的引用可以看出该 DataFrame 至少包含以下与本例直接相关的字段字段含义在本例中的用途name房源名称作为 hover 气泡的标题文本price每晚价格美元价格上下限过滤neighbourhood_group所在行政区行政区集合过滤latitude/longitude经纬度地图 marker 的坐标四、核心过滤逻辑filter_map 函数拆解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))]该函数签名与前端组件一一对应min_price、max_price来自两个gr.Numberboroughs来自gr.CheckboxGroup返回的被勾选选项列表。筛选采用 pandas 布尔索引三个条件同时成立df[neighbourhood_group].isin(boroughs)行政区 ∈ 用户勾选集合多选df[price] min_price价格严格大于下限df[price] max_price价格严格小于上限两端均为开区间。随后从筛选结果中取出name、price两列按行打包成text_list二元组列表作为地图气泡的自定义数据customdata用于 hover 时展示房源名称与价格。实操建议基于上面区间语义推断若希望边界值也被包含需把比较符改为/此外价格过滤是开区间设计当min_price与max_price过于接近或筛选条件过严时可能出现筛选结果为空的情形此时地图上不会有任何 marker属于符合过滤逻辑的正常表现可在真实业务中额外提示无匹配房源。五、绘制 Plotly Scattermapbox 地图并配置 hover 详情fig go.Figure(go.Scattermapbox( customdatatext_list, latfiltered_df[latitude].tolist(), lonfiltered_df[longitude].tolist(), modemarkers, markergo.scattermapbox.Marker( size6 ), hoverinfotext, hovertemplatebName/b: %{customdata[0]}brbPrice/b: $%{customdata[1]} ))关键配置项逐条说明lat/lon房源经纬度列表决定每个 marker 的地理位置modemarkers绘制散点marker.size6控制气泡大小customdatatext_list携带每行的(名称, 价格)附加数据不直接展示、仅供 hover 模板引用hoverinfotexthovertemplatehover 时按模板渲染。%{customdata[0]}取名称、%{customdata[1]}取价格b/br实现加粗与换行效果即名称 $价格的悬浮信息卡。接着通过update_layout设置地图的底图风格与视野fig.update_layout( mapbox_styleopen-street-map, hovermodeclosest, mapboxdict( bearing0, centergo.layout.mapbox.Center( lat40.67, lon-73.90 ), pitch0, zoom9 ), ) return figmapbox_styleopen-street-map选用 OpenStreetMap 免费底图因此无需配置 Mapbox access token 即可直接渲染这是该 demo 能零密钥开箱即用的关键center将视野中心固定到纽约市区附近lat 40.67 / lon -73.90zoom9控制缩放级别bearing0、pitch0保持地图正北朝向、无俯仰角hovermodeclosest让鼠标贴近某个气泡时只高亮并展示最近的那个避免重叠 marker 干扰阅读。六、Blocks 页面布局与组件组装with gr.Blocks() as demo: with gr.Column(): with gr.Row(): min_price gr.Number(value250, labelMinimum Price) max_price gr.Number(value1000, labelMaximum Price) boroughs gr.CheckboxGroup(choices[Queens, Brooklyn, Manhattan, Bronx, Staten Island], value[Queens, Brooklyn], labelSelect Boroughs:) btn gr.Button(valueUpdate Filter) map gr.Plot()页面结构与各组件职责gr.Column/gr.Row布局价格输入放在同一行Row整块 UI 垂直排布Column两个gr.Number提供价格上下限。默认值分别为 250 与 1000value250、value1000即应用打开时默认只展示 $250~$1000 区间的房源gr.CheckboxGroup提供纽约五大行政区多选。choices为 [Queens, Brooklyn, Manhattan, Bronx, Staten Island]默认勾选value[Queens, Brooklyn]。从 checkboxgroup.py 的源码注释可见choices决定可选项、value决定默认选中项组件默认以typevalue返回被选中的选项值列表正好对应filter_map的boroughs参数gr.Button文本为 Update Filter 的触发按钮gr.Plot地图输出容器不接受用户输入、仅承载函数返回的 Plotly Figure。七、事件绑定首屏加载与按钮点击双触发demo.load(filter_map, [min_price, max_price, boroughs], map) btn.click(filter_map, [min_price, max_price, boroughs], map) if __name__ __main__: demo.launch()demo.load(fn, inputs, outputs)页面加载完成即执行一次filter_map让用户无需点击就能先看到默认条件Queens Brooklyn、$250~$1000下的初始地图btn.click(fn, inputs, outputs)点击 Update Filter 按钮时把当前三个组件的值实时传给filter_map并刷新map两次事件绑定的inputs/outputs完全一致[min_price, max_price, boroughs]→map因此初始渲染与按钮刷新共用同一套过滤-绘图链路末尾demo.launch()启动本地服务若需要临时的公网分享地址可参照仓库指南为launch()追加shareTrue。八、底层原理gr.Plot 如何承载 Plotly 地图弄清gr.Plot在服务端做了什么有助于理解为什么返回一个普通go.Figure就能被前端渲染成可交互地图。核心实现在 gradio/components/plot.py组件声明其数据模型为PlotDataplot.py其字段为type取值限定为altair | bokeh | plotly | matplotlib与plot图内容的序列化字符串函数返回值会经过postprocessplot.py处理通过检测对象所属模块bokeh、altair、matplotlib等关键字自动判别图类型再各自序列化。对 Plotly 图走value.to_json()分支将 Figure 序列化为 JSON 字符串装入PlotData前端拿到PlotData后依据typeplotly使用 Plotly 运行时还原交互图形因此 Scattermapbox 的缩放、拖拽、hover 行为在浏览器中原生生效组件文档plot.py同时注明 Plot 几乎不充当输入组件本 demo 中它仅作输出使用符合组件定位。换句话说filter_map每次返回的新go.Figure都会在postprocess中被转成 Plotly JSON 推送到前端替换旧图由此实现改参数 → 重筛数据 → 重绘地图的完整交互闭环。九、总结与扩展思路整个 demo 呈现了一条非常典型的 Gradio 数据可视化应用范式真实外部数据集 pandas 过滤函数 Plotly 地图 Blocks 组件编排 双事件刷新。示例展示的是 Airbnb 房源分布但同一套骨架可平移复用到房价分布、POI 分布、订单地理可视化等任何带经纬度字段的 Plotly 地图场景。若基于本 demo 做进一步扩展可优先考虑的方向包括为gr.Number设置minimum/maximum约束输入合法性增加全部行政区快捷选项或在行政区全不选时给出提示用gr.Slider替代Number提供更顺滑的价格区间操作或在go.Scattermapbox中用marker.color按价格给气泡着色将价格维度从 hover 文本升级为视觉编码。这些改造都只需要在 run.py 的组件定义与filter_map内部增量完成不需要改动组件架构足见该模板的扩展弹性。【免费下载链接】gradioBuild and share delightful machine learning apps, all in Python. Star to support our work!项目地址: https://gitcode.com/GitHub_Trending/gr/gradio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价