Streamlit入门怎么读?GIS数据可视化项目实战教程(附:交互地图代码)
如果你正在搜索“Streamlit入门怎么读?GIS数据可视化项目实战教程(附:交互地图代码)”,大概率不是想看一堆抽象概念,而是想知道:Streamlit到底是什么、GIS项目里能不能用、如何快速做一个可交互的地图页面。本文用一个最小可运行的GIS数据可视化项目,带你从环境安装、数据读取、地图展示到侧边栏筛选,完成一个适合入门练习的Streamlit交互地图应用。

引言:Streamlit入门先理解它适合解决什么GIS问题
Streamlit是一个用Python快速构建数据应用的框架。对GIS学习者来说,它最大的价值不是替代QGIS、ArcGIS Pro或专业WebGIS框架,而是让你用很少的代码,把空间数据、统计图表、交互筛选和地图结果放到一个网页里。
在GIS数据可视化项目中,Streamlit特别适合这些场景:
- 把GeoJSON、Shapefile、CSV经纬度点数据快速做成网页预览工具。
- 给非技术同事提供一个可筛选、可查看地图的轻量应用。
- 在空间分析流程中展示中间结果,例如缓冲区分析、点位分布、网格统计。
- 制作GIS课程作业、数据分析作品集或内部数据检查面板。
本文的目标很明确:用Streamlit、GeoPandas、Folium完成一个可运行的交互地图示例。你可以把它理解为一个GIS版的Streamlit入门项目。
背景:为什么GIS读者学习Streamlit很有用
传统GIS软件擅长数据编辑、制图和空间分析,但如果你想把结果做成一个网页交互界面,通常会遇到几个门槛:
- QGIS或ArcGIS Pro项目文件不方便直接给没有软件环境的人查看。
- WebGIS开发需要学习HTML、JavaScript、Leaflet、OpenLayers等前端技术。
- Python脚本虽然能处理数据,但结果通常停留在命令行、图片或静态文件里。
- 空间分析项目需要反复调参数,最好有一个可视化交互界面。
Streamlit的优势在于:你主要写Python,不需要先掌握完整前端开发流程。对于已经会一点Pandas、GeoPandas或ArcPy的GIS学生和初级工程师来说,Streamlit入门成本相对低,能很快把空间数据处理结果包装成一个可交互页面。
简单理解:QGIS适合专业制图和数据处理,Streamlit适合把Python分析结果快速做成一个可分享的数据应用。
原理:Streamlit交互地图是怎么工作的
在这个项目里,Streamlit本身负责网页界面和交互控件,例如标题、侧边栏、下拉框、滑块和数据表。地图部分则交给Folium生成,Folium底层使用Leaflet来显示交互地图。
整个GIS数据可视化流程可以拆成五步:
- 使用Pandas或GeoPandas读取空间数据。
- 检查坐标字段或几何字段是否正确。
- 用Streamlit侧边栏设置筛选条件。
- 根据筛选后的数据生成Folium地图。
- 通过streamlit-folium把地图嵌入Streamlit页面。
这里有一个关键点:Web地图通常使用经纬度坐标,也就是WGS84坐标系,EPSG代码为4326。如果你的数据是投影坐标系,例如CGCS2000高斯投影、Web Mercator或地方坐标,直接放到Folium里可能会出现点位偏移、地图空白或位置完全错误。
本教程使用的Python库
| 库名 | 作用 | GIS项目中的用途 |
|---|---|---|
| streamlit | 构建网页应用 | 页面布局、侧边栏、筛选控件、数据表展示 |
| pandas | 表格数据处理 | 读取CSV、属性筛选、字段统计 |
| geopandas | 空间矢量数据处理 | 读取GeoJSON、Shapefile,处理几何对象和坐标系 |
| folium | 生成Leaflet交互地图 | 添加底图、点位、弹窗和图层 |
| streamlit-folium | 嵌入Folium地图 | 把Folium地图显示在Streamlit页面中 |
步骤:从零搭建Streamlit GIS数据可视化项目
步骤1:准备项目目录
建议先创建一个单独文件夹,避免和其他Python项目的依赖混在一起。项目结构可以这样安排:
streamlit-gis-demo/
├── app.py
├── data/
│ └── sample_points.csv
└── requirements.txt
其中,app.py是Streamlit主程序,data文件夹放GIS数据,requirements.txt记录依赖库。
步骤2:创建示例CSV点数据
为了让你可以直接复现,本文先使用CSV经纬度点数据。新建文件data/sample_points.csv,写入以下内容:
name,type,lon,lat,value
人民广场,公共服务,121.475,31.230,85
陆家嘴,商务区,121.506,31.245,92
徐家汇,商业区,121.437,31.188,78
虹桥枢纽,交通枢纽,121.327,31.200,88
五角场,商业区,121.514,31.303,74
张江高科,产业园区,121.587,31.207,90
实际项目中,你可以替换为自己的监测点、POI点、样方点、设备点位或业务网点数据。只要包含经度字段和纬度字段,就可以按照本文方式快速展示。
步骤3:安装Python依赖
在项目目录下创建requirements.txt:
streamlit
pandas
geopandas
folium
streamlit-folium
然后在命令行安装:
pip install -r requirements.txt
如果GeoPandas安装失败,通常和GDAL、Fiona、pyproj等空间依赖有关。对初学者来说,推荐使用conda环境安装:
conda create -n streamlit-gis python=3.11
conda activate streamlit-gis
conda install -c conda-forge geopandas folium streamlit streamlit-folium pandas
步骤4:编写Streamlit交互地图代码
新建app.py,写入下面这段完整代码:
import streamlit as st
import pandas as pd
import folium
from streamlit_folium import st_folium
st.set_page_config(
page_title="Streamlit GIS数据可视化示例",
layout="wide"
)
st.title("Streamlit GIS数据可视化项目")
st.write("使用CSV经纬度点数据,构建一个可筛选的交互地图。")
@st.cache_data
def load_data():
df = pd.read_csv("data/sample_points.csv")
return df
df = load_data()
required_fields = {"name", "type", "lon", "lat", "value"}
missing_fields = required_fields - set(df.columns)
if missing_fields:
st.error(f"数据缺少必要字段:{missing_fields}")
st.stop()
st.sidebar.header("筛选条件")
type_options = sorted(df["type"].unique().tolist())
selected_types = st.sidebar.multiselect(
"选择点位类型",
options=type_options,
default=type_options
)
min_value, max_value = int(df["value"].min()), int(df["value"].max())
value_range = st.sidebar.slider(
"选择数值范围",
min_value=min_value,
max_value=max_value,
value=(min_value, max_value)
)
filtered = df[
(df["type"].isin(selected_types)) &
(df["value"].between(value_range[0], value_range[1]))
].copy()
st.subheader("数据预览")
st.dataframe(filtered, use_container_width=True)
if filtered.empty:
st.warning("当前筛选条件下没有数据,请调整筛选条件。")
st.stop()
center_lat = filtered["lat"].mean()
center_lon = filtered["lon"].mean()
m = folium.Map(
location=[center_lat, center_lon],
zoom_start=11,
tiles="OpenStreetMap"
)
for _, row in filtered.iterrows():
popup_html = f"""
<b>名称:</b>{row['name']}<br>
<b>类型:</b>{row['type']}<br>
<b>数值:</b>{row['value']}
"""
folium.CircleMarker(
location=[row["lat"], row["lon"]],
radius=8,
popup=folium.Popup(popup_html, max_width=250),
tooltip=row["name"],
color="blue",
fill=True,
fill_color="orange",
fill_opacity=0.75
).add_to(m)
st.subheader("交互地图")
st_folium(m, width=None, height=600)
st.caption("提示:请确保经纬度字段使用WGS84坐标系,字段顺序为lon经度、lat纬度。")
步骤5:运行Streamlit应用
在项目目录下执行:
streamlit run app.py
浏览器会自动打开本地页面。你应该能看到三个核心部分:
- 左侧侧边栏:用于筛选点位类型和数值范围。
- 数据表:显示筛选后的属性数据。
- 交互地图:点位会根据筛选结果实时变化,点击点位可以查看弹窗信息。
步骤6:替换为GeoJSON数据
如果你的数据不是CSV,而是GeoJSON,可以用GeoPandas读取。假设文件为data/points.geojson,关键代码可以改成:
import geopandas as gpd
@st.cache_data
def load_geojson():
gdf = gpd.read_file("data/points.geojson")
if gdf.crs is None:
st.warning("GeoJSON未声明坐标系,请确认是否为EPSG:4326。")
else:
gdf = gdf.to_crs(epsg=4326)
gdf["lon"] = gdf.geometry.x
gdf["lat"] = gdf.geometry.y
return gdf
这段代码的重点是to_crs(epsg=4326)。在Streamlit交互地图项目中,坐标系转换不是可选项,而是保证地图点位正确显示的基础检查。
常见坑:Streamlit交互地图代码能运行但结果不对
坑1:经纬度字段写反
Folium添加点位时,location参数的顺序是纬度在前、经度在后,也就是:
location=[lat, lon]
但CSV字段通常写成lon、lat。如果你误写成location=[lon, lat],点位可能飞到其他国家,甚至地图上看不到。
坑2:数据坐标系不是WGS84
Web地图常用经纬度坐标显示点位。如果你的数据坐标看起来像几百万、几十万,而不是经度120左右、纬度30左右,那很可能是投影坐标。此时需要先用QGIS、ArcGIS Pro或GeoPandas转换到EPSG:4326。
坑3:Streamlit每次交互都会重新执行脚本
Streamlit的执行机制是:用户调整一个控件,脚本会从上到下重新运行。读取大文件、复杂空间分析或远程数据库查询如果不做缓存,页面会明显变慢。
本文代码中使用了st.cache_data缓存CSV读取结果。实际项目中,如果读取PostGIS、GeoPackage或大型GeoJSON,也建议对数据加载函数加缓存。
坑4:GeoJSON太大导致页面卡顿
Streamlit可以快速做GIS数据可视化,但不适合直接把几十万条矢量要素全部塞进浏览器地图。遇到大数据量时,可以考虑:
- 先按区域、类型或时间筛选数据。
- 对线面数据做简化,减少顶点数量。
- 使用聚合点、网格统计或热力图表达。
- 把复杂空间查询放到PostGIS中完成。
- 真正的大规模WebGIS项目使用瓦片服务、矢量瓦片或专业地图服务。
坑5:部署后找不到数据文件
本地运行正常,部署后报错“file not found”,通常是数据路径问题。建议使用相对路径,并确保data文件夹随项目一起上传。不要写成本机绝对路径,例如C盘目录或个人桌面路径。
方法比较:Streamlit、QGIS和传统WebGIS该怎么选
| 方案 | 适合场景 | 优点 | 局限 |
|---|---|---|---|
| Streamlit | Python分析结果展示、轻量GIS数据可视化、内部工具 | 上手快,代码少,适合数据分析流程 | 复杂地图交互能力有限,大数据量渲染需优化 |
| QGIS | 专业制图、数据检查、空间分析、坐标转换 | GIS功能完整,插件丰富,适合桌面处理 | 不适合直接发布为多人访问的网页应用 |
| ArcGIS Pro | 企业级GIS生产、制图、空间分析和平台集成 | 工具链完整,适合规范化生产环境 | 授权成本较高,轻量网页应用开发不如Streamlit直接 |
| Leaflet或OpenLayers | 正式WebGIS系统、复杂地图交互、前端定制 | 前端控制能力强,适合产品级开发 | 需要掌握JavaScript和前端工程 |
| PostGIS加WebGIS框架 | 空间数据库查询、多用户系统、大规模业务数据 | 查询能力强,可扩展性好 | 架构复杂,入门成本高于Streamlit |
如果你是GIS学生或刚入门的空间数据分析师,建议先用Streamlit完成小型项目,再逐步学习PostGIS、Leaflet或OpenLayers。这样学习路径更平滑,也更容易形成可展示的作品。
检查清单:发布前确认这些GIS细节
- 数据字段:是否包含名称、分类、经度、纬度等必要字段。
- 坐标顺序:Folium中是否使用location=[lat, lon]。
- 坐标系:点位是否已经转换为EPSG:4326。
- 空值处理:经纬度字段是否有空值、字符串或异常值。
- 筛选逻辑:侧边栏筛选后是否可能出现空数据,并给出提示。
- 性能优化:大文件读取是否使用st.cache_data。
- 文件路径:部署环境中data文件夹是否存在,路径是否为相对路径。
- 地图中心:是否根据筛选后数据动态计算中心点。
- 弹窗内容:是否只展示必要字段,避免一次性塞入过多属性。
- 数据安全:内部敏感点位不要直接部署到公开访问地址。
FAQ:Streamlit入门与GIS交互地图常见问题
Streamlit入门需要先会前端吗?
不需要。Streamlit的核心优势就是用Python写网页应用。你只需要掌握基本Python语法、Pandas数据处理和一些GIS数据概念,就可以完成入门级GIS数据可视化项目。
Streamlit能不能直接读取Shapefile?
可以。使用GeoPandas的gpd.read_file()可以读取Shapefile。但要注意Shapefile通常由多个文件组成,例如.shp、.shx、.dbf、.prj,部署时必须一起上传。读取后建议检查坐标系,并转换为EPSG:4326再放到交互地图里。
Streamlit交互地图代码为什么显示空白?
常见原因有四个:经纬度字段为空、经纬度顺序写反、坐标系不是WGS84、筛选条件导致数据为空。建议先用st.dataframe查看筛选后的数据,再检查lon和lat是否是合理范围。
Streamlit适合做正式WebGIS系统吗?
Streamlit适合快速原型、内部工具、数据分析展示和课程项目。如果要做高并发、多角色权限、复杂空间编辑、地图服务管理的正式WebGIS系统,通常应考虑PostGIS、GeoServer、Leaflet、OpenLayers、Cesium等更完整的技术栈。
GIS数据可视化项目用Folium还是PyDeck?
Folium更适合Leaflet风格的传统二维交互地图,代码直观,适合入门。PyDeck适合点云、大量点位、3D柱状图、轨迹和WebGL可视化。如果你的目标是先完成Streamlit入门项目,Folium更容易上手。
Streamlit能连接PostGIS吗?
可以。常见做法是使用SQLAlchemy、psycopg或GeoPandas从PostGIS读取查询结果。实际项目中建议只查询当前页面需要的数据,不要一次性把整库空间数据加载到Streamlit中。
结论:用一个小项目完成Streamlit入门最有效
学习Streamlit入门,最好的方式不是先背API,而是从一个具体GIS数据可视化项目开始。本文示例用CSV点数据、侧边栏筛选和Folium交互地图,完成了一个可运行、可修改、可扩展的空间数据展示应用。
你可以在这个基础上继续扩展:接入GeoJSON或Shapefile、加入行政区边界、连接PostGIS、增加统计图表,或者把空间分析结果作为地图图层展示。只要记住三个核心检查点:字段正确、坐标系正确、数据量可控,Streamlit就能成为GIS学习和项目演示中非常实用的工具。