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

发布时间:2026/11/3 1:23:56

Gradio + Plotly 交互地图实战:用 gr.Plot 构建纽约 Airbnb 房源筛选应用 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),仅供参考
延伸阅读

更多相关文章

2026/11/2 16:45:20

计及碳排放的多微电网ADMM分布式电能交互优化

多微电网的分布式运行策略,这几年在学术圈和工程圈都特别热。我平时做能源系统优化,用Matlab复现过不少相关算法,其中“计及碳排放、基于ADMM的多微网电能交互分布式优化”这套流程,算是我踩坑比较多、收获也最大的一块。标题里这…

2026/11/3 0:14:35

uC/OS-III官方源码下载与移植实战指南:从结构拆解到工程落地

简介:这是Micrium官方发布的uC/OS-III实时操作系统完整源代码压缩包,适合嵌入式开发人员、高校学生以及需要评估或移植RTOS的工程师。它把RTOS的核心内核、任务管理、时间管理、内存管理、信号量、互斥量、消息队列、软件定时器等模块全部以C源码呈现&am…

2026/11/2 23:28:24

Typora使用完全指南:从安装配置到导出与免费替代方案

Typora 是一款以“所见即所得”为核心的本地 Markdown 编辑器。它和大多数编辑器不同的地方在于:你输入#时看到的是符号,按下空格后行内内容立即渲染成一级标题;输入**加粗**时不会一直保留星号,而是直接把文字以加粗样式显示。这…

2026/11/3 13:13:23

漏洞挖掘实战:从扫描器依赖到攻击面建模

1. 项目背景与核心挑战 "挖洞"这个术语在安全测试领域特指漏洞挖掘工作。作为从业十余年的白帽子,我经历过太多投入数百小时却颗粒无收的项目。去年某金融系统的渗透测试中,团队累计投入327人天只发现2个低危漏洞,客户质疑报告价值…

2026/11/3 13:13:23

paperclip 实战:Node.js + React 构建 AI agent 可观测面板

1. 从 paperclip 这个名字说起:它到底想解决什么问题第一次看到paperclip这个项目名,我脑子里蹦出来的画面是那个经典的 Office 助手——一个会跳出来问“需要帮忙吗”的小回形针。但放到 2026 年的技术语境里,这个名字其实挺有意思&#xff…

2026/11/3 13:13:23

Gradle 7.x仓库收口:repositoriesMode三模式与依赖治理

经常看到有团队把 Gradle 从 6.x 拉到 7.x,改完 wrapper、跑一次 sync,屏幕上直接糊出来一行红字:Build was configured to prefer settings repositories over project repositories but repository maven was added by build file app/buil…

2026/11/3 13:13:23

回形针的弹性原理与隐藏技能:从力学到选购一篇讲透

桌上那盒回形针,你大概从来没正眼看过它。它便宜到按斤装、论盒卖,长得也差不多:一段两头弯起来的铁丝。可就是这根铁丝,每年在全球要被用掉几十亿枚。它夹得住两页便利贴,也夹得住一摞报销单;它可以是书签…

2026/11/3 13:13:23

LeetCode 56题:合并区间算法详解与应用

1. 合并区间问题概述 合并区间是LeetCode上经典的数组处理问题,编号为56题,同时也是hot100高频面试题库中的必刷题目。这道题考察的是对区间重叠情况的判断与处理能力,在实际开发中有着广泛的应用场景,比如日程安排系统、会议室预…

2026/11/3 13:08:21

Oracle数据库核心进程与内存结构深度解析

1. 项目概述 "深入理解Oracle数据库核心进程与内存结构"这个题目看似简单,却涵盖了Oracle数据库最核心的架构知识。作为数据库系统原理课程的经典考题,它考察的不仅是概念记忆,更是对数据库运行机制的深刻理解。我在实际DBA工作中发…

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32实战:基于MAX14431数字隔离器的SPI隔离通信方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

工业SPI隔离通信设计:MAX14431BAEE+与STM32L4A6RG实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 1:04:48

STM32+NRF24L01无线抢答器:硬件设计、通信协议与低功耗实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/3 7:47:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/2 6:39:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑