将比例尺(以米为单位)添加到Stata中GPS坐标的散点图中

将比例尺(以米为单位)添加到Stata中GPS坐标的散点图中,gps,stata,scatter-plot,scatter,Gps,Stata,Scatter Plot,Scatter,我正在Stata使用双向散射绘制一系列GPS点。这只是为了可视化点的位置,以便进行快速验证。我想为x轴和y轴添加一个比例尺,以了解点之间的实际距离 下面是一些代码,用于输入一些坐标并绘制散点图,指定轴范围: * Input example data clear input key lat lon 1 -17.01639 36.11884 2 -17.01669 36.11916 3 -17.01692 36.11666 4

我正在Stata使用双向散射绘制一系列GPS点。这只是为了可视化点的位置,以便进行快速验证。我想为x轴和y轴添加一个比例尺,以了解点之间的实际距离

下面是一些代码,用于输入一些坐标并绘制散点图,指定轴范围:

* Input example data
    clear
    input key lat lon
    1   -17.01639   36.11884
    2   -17.01669   36.11916
    3   -17.01692   36.11666
    4   -17.01575   36.11607
    5   -17.01551   36.11619
    6   -17.01543   36.11665
    7   -17.01581   36.11706
    8   -17.01665   36.11672
    9   -17.01543   36.11612
    10  -17.01724   36.11668
    end

* Install Geodist (we will need this later)
    cap which geodist
        if _rc == 111 ssc install geodist   // Installs geodist if necessary

* Create y/x axis ranges using min and max latitude and longitude
    sort lat
    local ymin = lat[1]
    local ymax = lat[_N]
    local ydelta = (`ymax' - `ymin')/3

    sort lon
    local xmin = lon[1]
    local xmax = lon[_N]
    local xdelta = (`xmax' - `xmin')/3

* Graph points
    twoway scatter lat lon,                                 ///
        ylabel(`ymin'(`ydelta')`ymax', angle(forty_five))   ///
        xlabel(`xmin'(`xdelta')`xmax')
你应该得到一个可爱的基本散点图。这很好,但我不知道这些点之间的实际距离有多远。现在,我们可以通过以下方法了解最小和最大纬度/经度之间的距离:

* Store x and y ranges in locals
    geodist `ymin' `xmin' `ymax' `xmin'
    local yrange = `r(distance)'

    geodist `ymin' `xmin' `ymin' `xmax'
    local xrange = `r(distance)'
对于该数据,y跨度为0.2km,x跨度为0.329km

注:我知道,在地球的球形投影上,ymin和ymax之间的距离可能无法完美映射到该距离的子集上(例如,从ymin到ymax/2的距离可能与ymin和ymax之间距离的一半不完全相同)。但对于我需要这种可视化的原因,以及这些数据通常聚集在彼此相距2公里的范围内这一事实,它已经足够精确了


那么,我如何为x和y中的每一个创建一个比例尺来显示,例如,100米看起来是什么样子?在本例中,y比例看起来与x比例不同,因此我可能需要找到一种方法来更改y范围和x范围,以便它们可以表示相同的比例

我不确定这是否正是您想要的,我没有在Stata中使用
geo2xy
的任何经验,但是使用常规
双向
和一点代数,您可以获得这些比例的近似值(特别是因为您说您正在进行小规模的工作,近似是可以的)

我把代码放在下面,但有点长,所以这里是执行摘要:

首先,我们要计算1米距离的纬度和经度值。我们可以这样做,因为我们有以公里为单位的范围,以及纬度和经度的最小值和最大值

然后,我把这个距离放在我们之前的散点图上的双向连接图中

要获得1米距离的值,请执行以下操作:

* Store x and y ranges in locals
    geodist `ymin' `xmin' `ymax' `xmin'
    local yrange = `r(distance)'

    geodist `ymin' `xmin' `ymin' `xmax'
    local xrange = `r(distance)'
我们可以假设这是非常线性的(0映射到0公里,
xmax xmin
映射到
xrange
km),所以为了得到一米,我们可以把它插入一个线性方程
y=mx+b
,注意b是0,我们的
slope=xrange/(xmax xmin)
。然后,我们可以设置
1米=1/1000*1/slope
1米=(xmax xmin)/(xrange*1000)
。在我的示例中,我使用100米,因为1米太小,但要更改缩放比例,您只需将
1/1000
更改为您想要的任何比例。 然后,我们可以对y轴执行相同的操作,并将它们添加到数据集中并绘制它们的图形

下面是我在运行上面的代码后使用的代码:

local xmeter = (`xmax'-`xmin')/(`xrange'*10)
local ymeter = (`ymax'-`ymin')/(`yrange'*10)
local xbit = (`xmax'-`xmin')/20
local ybit = (`ymax'-`ymin')/20
local xmin_and_bit = `xmin' + `xbit'
local ymin_and_bit = `ymin' + `ybit'
local xmin_and_bit_and_one_meter = `xmin' + `xbit' + `xmeter'
local ymin_and_bit_and_one_meter = `ymin' + `ybit' + `ymeter'

// generate a dummy variable for data vs lengths
gen scale = 0

// add four observations for our distance markers
local new_obs_num = _N + 4
set obs `new_obs_num'

// point for ymin and xmin+bit
replace scale = 1 if _n == _N - 3
replace lat = `ymin' if _n == _N - 3
replace lon = `xmin_and_bit' if _n == _N - 3

// point for ymin and xmin+bit+1
replace scale = 1 if _n == _N - 2
replace lat = `ymin' if _n == _N - 2
replace lon = `xmin_and_bit_and_one_meter' if _n == _N - 2

// point for ymin+bit and xmin
replace scale = 2 if _n == _N - 1
replace lat = `ymin_and_bit' if _n == _N - 1
replace lon = `xmin' if _n == _N - 1

// point for ymin+bit+1 and xmin
replace scale = 2 if _n == _N
replace lat = `ymin_and_bit_and_one_meter' if _n == _N
replace lon = `xmin' if _n == _N


// now graph the scatter plot if scale == 0, 
// the x 100 meters if scale == 1, 
// and y 100 meters if scale == 2
twoway (scatter lat lon if scale == 0) ///
    (connected lat lon if scale == 1, ///
        msymbol(+) lcolor(black) mcolor(black)) ///
    (connected lat lon if scale == 2, ///
        msymbol(+) lcolor(black) mcolor(black)), ///
    ylabel(`ymin'(`ydelta')`ymax', angle(forty_five))   ///
    xlabel(`xmin'(`xdelta')`xmax') ///
    legend(off) ///
    note("Points are points and lines show 100 meters")

我不确定这是否正是您想要的,我没有在Stata中使用
geo2xy
的任何经验,但是使用常规
two-way
和一点代数,您可以获得这些尺度的近似值(特别是因为您说您在小尺度上工作,近似是可以的)

我把代码放在下面,但有点长,所以这里是执行摘要:

首先,我们要计算1米距离的纬度和经度值。我们可以这样做,因为我们有以公里为单位的范围,以及纬度和经度的最小值和最大值

然后,我把这个距离放在我们之前的散点图上的双向连接图中

要获得1米距离的值,请执行以下操作:

* Store x and y ranges in locals
    geodist `ymin' `xmin' `ymax' `xmin'
    local yrange = `r(distance)'

    geodist `ymin' `xmin' `ymin' `xmax'
    local xrange = `r(distance)'
我们可以假设这是非常线性的(0映射到0公里,
xmax xmin
映射到
xrange
km),所以为了得到一米,我们可以把它插入一个线性方程
y=mx+b
,注意b是0,我们的
slope=xrange/(xmax xmin)
。然后,我们可以设置
1米=1/1000*1/slope
1米=(xmax xmin)/(xrange*1000)
。在我的示例中,我使用100米,因为1米太小,但要更改缩放比例,您只需将
1/1000
更改为您想要的任何比例。 然后,我们可以对y轴执行相同的操作,并将它们添加到数据集中并绘制它们的图形

下面是我在运行上面的代码后使用的代码:

local xmeter = (`xmax'-`xmin')/(`xrange'*10)
local ymeter = (`ymax'-`ymin')/(`yrange'*10)
local xbit = (`xmax'-`xmin')/20
local ybit = (`ymax'-`ymin')/20
local xmin_and_bit = `xmin' + `xbit'
local ymin_and_bit = `ymin' + `ybit'
local xmin_and_bit_and_one_meter = `xmin' + `xbit' + `xmeter'
local ymin_and_bit_and_one_meter = `ymin' + `ybit' + `ymeter'

// generate a dummy variable for data vs lengths
gen scale = 0

// add four observations for our distance markers
local new_obs_num = _N + 4
set obs `new_obs_num'

// point for ymin and xmin+bit
replace scale = 1 if _n == _N - 3
replace lat = `ymin' if _n == _N - 3
replace lon = `xmin_and_bit' if _n == _N - 3

// point for ymin and xmin+bit+1
replace scale = 1 if _n == _N - 2
replace lat = `ymin' if _n == _N - 2
replace lon = `xmin_and_bit_and_one_meter' if _n == _N - 2

// point for ymin+bit and xmin
replace scale = 2 if _n == _N - 1
replace lat = `ymin_and_bit' if _n == _N - 1
replace lon = `xmin' if _n == _N - 1

// point for ymin+bit+1 and xmin
replace scale = 2 if _n == _N
replace lat = `ymin_and_bit_and_one_meter' if _n == _N
replace lon = `xmin' if _n == _N


// now graph the scatter plot if scale == 0, 
// the x 100 meters if scale == 1, 
// and y 100 meters if scale == 2
twoway (scatter lat lon if scale == 0) ///
    (connected lat lon if scale == 1, ///
        msymbol(+) lcolor(black) mcolor(black)) ///
    (connected lat lon if scale == 2, ///
        msymbol(+) lcolor(black) mcolor(black)), ///
    ylabel(`ymin'(`ydelta')`ymax', angle(forty_five))   ///
    xlabel(`xmin'(`xdelta')`xmax') ///
    legend(off) ///
    note("Points are points and lines show 100 meters")

如果要使用地理坐标创建地图,首先需要将这些坐标转换为平面(x,y)坐标。使用
geo2xy
(来自SSC),您可以使用谷歌地图使用的相同投影,这样您创建的地图将与您在谷歌地图上观察到的比例完全相同。因为您需要基于距离单位的坐标,所以我选择了一个真正的墨卡托投影,它以米为单位创建(x,y)坐标。默认情况下,投影以中经度为中心,这意味着x坐标与地图中心的距离以米为单位。y坐标距赤道以米为单位。要使它们在地图中间居中,只需将它们与平均值偏移即可

在Stata中创建贴图时,需要确保创建具有正确比例的贴图区域(xsize()和ysize()与距离成比例)

以下是生成的地图:

如果要显示轴单位(以米为单位),可以删除xlabel()和ylabel()行。如果这样做,Stata可能会重新缩放每个轴以适应良好的间隔,因此会稍微改变比例。如果我让Stata决定标签,地图会是这样的:


如果要创建带有地理坐标的地图,首先需要将这些坐标转换为平面(x,y)坐标。使用
geo2xy
(来自SSC),您可以使用谷歌地图使用的相同投影,这样您创建的地图将具有完全相同的pr