如何基于PyMongo、Plotly与Mapbox批量绘制多组查询坐标点
问题描述
项目开发需实现MongoDB查询结果中多组坐标点的地图绘制功能,当前单条查询结果的坐标绘制可正常运行,但无法正确遍历查询返回的结果集实现多坐标批量绘制,多次调试未解决。
原有单结果正常运行的代码如下:
countE2 = mydb.results.find({"d.latitude":{"$gt":0},"d.longitude":{"$gt":0}},{"d.latitude":1, "d.longitude": 1,"a":1,"u.Server":1}).limit(10).sort('t', pymongo.DESCENDING) for resultado in countE2: lat = resultado["d"]["latitude"] lon = resultado["d"]["longitude"] ip = resultado["a"] server = resultado["u"]["Server"] us_cities = [lat,lon,ip,server] y = us_cities print(y) fig = px.scatter_mapbox(y,lat=[y[0]], lon=[y[1]],hover_name=[y[2]],hover_data=[[y[3]],[y[3]]],color_discrete_sequence=["green"], zoom=3, height=1000) print(fig) fig.update_layout(mapbox_style="dark", mapbox_accesstoken=token) fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
上述查询countE2会返回多条结果,现有代码仅支持单条结果绘制,需适配多结果批量绘制场景。
问题根因
原有逻辑在遍历MongoDB游标时,每次循环都会覆盖变量y的值,循环结束后y仅保留最后一条查询结果的数据;同时调用px.scatter_mapbox时传入的是单元素列表,自然只能渲染1个点位。
修复代码
plotly.express.scatter_mapbox原生支持传入等长的多值列表批量渲染点位,不需要在循环中重复调用绘图接口,只需在遍历游标时收集所有点位的属性,一次性传入绘图接口即可:
countE2 = mydb.results.find( {"d.latitude":{"$gt":0},"d.longitude":{"$gt":0}}, {"d.latitude":1, "d.longitude": 1,"a":1,"u.Server":1} ).limit(10).sort('t', pymongo.DESCENDING) # 初始化列表存储所有点位的对应属性 lat_list = [] lon_list = [] ip_list = [] server_list = [] # 遍历游标收集全量点位数据 for resultado in countE2: lat_list.append(resultado["d"]["latitude"]) lon_list.append(resultado["d"]["longitude"]) ip_list.append(resultado["a"]) server_list.append(resultado["u"]["Server"]) print([lat_list[-1], lon_list[-1], ip_list[-1], server_list[-1]]) # 批量传入全量点位数据绘图 fig = px.scatter_mapbox( lat=lat_list, lon=lon_list, hover_name=ip_list, hover_data={"所属服务端": server_list}, color_discrete_sequence=["green"], zoom=3, height=1000 ) fig.update_layout(mapbox_style="dark", mapbox_accesstoken=token) fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0}) fig.show()
注意事项
- MongoDB的
find()方法返回的是游标对象,完整遍历一次后就会耗尽,如果后续需要复用查询结果,可以在查询后先转成列表:countE2 = list(mydb.results.find(...)) - 原有代码的
hover_data重复传入了两次相同的server字段,修复后改用字典形式自定义悬浮展示的字段名,无需重复传值
内容的提问来源于stack exchange,提问作者dopeb3ar2
相关产品推荐
相关产品推荐

