我主要使用 Folium 和 Streamlit 来完成此任务。我已经成功绘制了 2 个数据集并绘制了随机红色标记。我的计划是让地图与鼠标点击交互。我无法超越这个时间,因为我的问题是为什么每次我点击地图上的任何地方它都会重新加载。我试图在我的 Folium 地图中不再使用 Javascript,但 Streamlit 这么慢是没有意义的。
这就是我使用cache_data装饰器的方式。基本上,一个接受所有数据类型的函数(是的,它不是一个漂亮的函数)。请告诉我我做错了什么。
@st.cache_data
def load_data(file_url):
if pathlib.Path(file_url).suffix == ".json":
# df = pd.read_json(file_url)
df = json.load(open(file_url))
elif pathlib.Path(file_url).suffix == ".xlsx":
df = pd.read_excel(file_url, sheet_name="Sheet1")
return df
场景一:正确使用st.cache_data
您的 load_data 函数看起来很适合缓存数据。只需确保它仅用于数据加载,而不用于生成地图本身。
@st.cache_data
def load_data(file_url):
if pathlib.Path(file_url).suffix == ".json":
df = json.load(open(file_url))
elif pathlib.Path(file_url).suffix == ".xlsx":
df = pd.read_excel(file_url, sheet_name="Sheet1")
return df
场景二:单独地图渲染
单独创建 Folium 地图,而不将其包装在缓存装饰器中。
def create_map(data):
m = folium.Map(location=[latitude, longitude], zoom_start=10)
for index, row in data.iterrows():
folium.Marker([row['lat'], row['lon']], popup=row['name']).add_to(m)
return m
场景3:处理点击事件:
Streamlit 本身并不直接处理 Folium 的交互性。使用streamlit-folium库,它允许您与Streamlit中的Folium地图进行交互。
import streamlit_folium as st_folium
st_data = st_folium.folium_static(m)
click_location = st_data['last_clicked']
if click_location:
st.write(f"Clicked at: {click_location}")
场景 4:防止完整脚本重新运行
使用 st.session_state 在重新运行时保留状态。
if "clicks" not in st.session_state:
st.session_state["clicks"] = []
if click_location:
st.session_state["clicks"].append(click_location)
st.write(st.session_state["clicks"])