我想根据圆半径(以公里为单位)检索最近的坐标点,并将结果绘制在散点图框上。但我不知道如何绘制圆形半径。有人知道如何绘制圆形半径吗?
到目前为止,我的结果只是圆半径中的数据,没有圆的形状。这是我的代码
import plotly.graph_objects as go
import plotly.express as px
from math import radians, cos, sin, asin, sqrt
def haversine(lon1, lat1, lon2, lat2):
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
r = 6371
return c * r
center_point = pd.DataFrame({'Longitude':[long_input], 'Latitude':[lat_input]})
test_point = df_latlong[['Longitude','Latitude']].reset_index().drop('index',axis=1)
lat1 = center_point['Latitude'][0]
lon1 = center_point['Longitude'][0]
df_nearest = []
for i, (index, row) in enumerate(df_latlong.iterrows()):
lat2 = test_point['Latitude'][i]
lon2 = test_point['Longitude'][i]
a = haversine(lon1, lat1, lon2, lat2)
df_nearest.append(a)
df_latlong['Distance'] = df_nearest
df_radius = df_latlong[df_latlong['Distance'] <= 5] #5 kilometers for radius
fig_map3 = px.scatter_mapbox(df_radius, lon=df_radius['Longitude'], lat=df_radius['Latitude'],
hover_name='#WELL', zoom=9, width=300, height=500)
fig_map3.update_layout(mapbox_style='open-street-map', margin={'r':0, 't':0, 'l':0, 'b':0})
fig_map3.show()
它具有基于我在 center_point 中定义的质心的圆形半径。我怎样才能画出这样的黑色圆圈?半径有5公里。任何想法?谢谢!
最佳答案
首先,我在与屏幕截图中显示的数据相同的地理区域中创建了一些示例数据。
然后,我们可以使用 the approximation 计算半径为 r 的圆的(纬度、经度)点、圆心和样本点数量。由 @Stéphane 给出(对于你的问题,你想要的中心点周围 5 公里的半径足够小,这个近似值可以很好地保持)。
注意:我尝试[失败]使用geog.propogate
计算圆的精确坐标,如here所述。 ,但它没有为围绕中心坐标的圆生成正确的坐标。
然后您可以将圆的(纬度、经度)点传递给 go.Scattermapbox
,将模式设置为“线条”,并将轨迹添加到您的图形中。
import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
from math import radians, cos, sin, asin, sqrt, pi
def haversine(lon1, lat1, lon2, lat2):
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
r = 6371
return c * r
## create a sample dataframe to reproduce your data
lat_input, long_input = -0.622929, 117.575513,
lat_min, lat_max = -0.59, -0.68
long_min, long_max = 117.543, 117.614
np.random.seed(42)
df_latlong = pd.DataFrame({
'Latitude': np.random.uniform(lat_min, lat_max, size=20),
'Longitude': np.random.uniform(long_min, long_max, size=20),
'#WELL': ["TN-test"]*20
})
center_point = pd.DataFrame({'Longitude':[long_input], 'Latitude':[lat_input]})
test_point = df_latlong[['Longitude','Latitude']].reset_index().drop('index',axis=1)
lat1 = center_point['Latitude'][0]
lon1 = center_point['Longitude'][0]
df_nearest = []
for i, (index, row) in enumerate(df_latlong.iterrows()):
lat2 = test_point['Latitude'][i]
lon2 = test_point['Longitude'][i]
a = haversine(lon1, lat1, lon2, lat2)
df_nearest.append(a)
df_latlong['Distance'] = df_nearest
df_radius = df_latlong[df_latlong['Distance'] <= 5] #5 kilometers for radius
fig_map3 = px.scatter_mapbox(df_radius, lon=df_radius['Longitude'], lat=df_radius['Latitude'],
hover_name='#WELL', zoom=9, width=300, height=500)
radius = 5 * 1000 # m - the following code is an approximation that stays reasonably accurate for distances < 100km
# parameters
N = 360 # number of discrete sample points to be generated along the circle
# generate points
circle_lats, circle_lons = [], []
for k in range(N):
# compute
angle = pi*2*k/N
dx = radius*cos(angle)
dy = radius*sin(angle)
circle_lats.append(lat1 + (180/pi)*(dy/6378137))
circle_lons.append(lon1 + (180/pi)*(dx/6378137)/cos(lat1*pi/180))
circle_lats.append(circle_lats[0])
circle_lons.append(circle_lons[0])
fig_map3.add_trace(go.Scattermapbox(
lat=circle_lats,
lon=circle_lons,
mode='lines',
marker=go.scattermapbox.Marker(
size=1, color="BlueViolet"
),
))
fig_map3.update_layout(mapbox_style='open-street-map', margin={'r':0, 't':0, 'l':0, 'b':0}, width=500)
fig_map3.show()
关于python - 如何在散点图盒上绘制圆形半径图(Plotly Python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74793322/