简体   繁体   English

在 python3 中绘制散点图 plot,其中 x 轴是纬度/经度,单位为千米,y 轴是深度

[英]Plotting a scatter plot in python3 where x axis is latitude/longitude in km and y axis is depth

I am trying to find the best way to plot some data.我试图找到 plot 一些数据的最佳方法。 Basically I have a data file that has the columns latitude, longitude, depth, sample_ID,Group_ID.基本上我有一个数据文件,其中包含纬度、经度、深度、sample_ID、Group_ID 列。 I would like to generate a 2-D scatter plot where y is depth and x is distance in km from north to south (or have transect distances calculated relative to the first station sampled in the indicated orientation), similar to an ODV style map like the one below:我想生成一个二维散点图 plot ,其中 y 是深度,x 是从北到南的距离(以公里为单位)(或相对于在指示方向采样的第一个站点计算横断面距离),类似于 ODV 样式 map下面的一个:

在此处输入图像描述

UPDATED更新

I wanted to add a little more information to my initial question.我想在我最初的问题中添加更多信息。 After some more searching and testing I found a possible solution in R using the geosphere package and the distGEO function to convert my coordinates to distance in km which then can be mapped.经过更多的搜索和测试,我在 R 中找到了一个可能的解决方案,使用地圈 package 和 distGEO ZC1C1C425268E68385D1AB5074C17A94F14Z 将我的坐标转换为距离然后可以映射。 ( https://www.rdocumentation.org/packages/geosphere/versions/1.5-10/topics/distGeo ) https://www.rdocumentation.org/packages/geosphere/versions/1.5-10/topics/distGeo

If anyone knows a python way to do this though that'd be great!如果有人知道 python 方法来做到这一点,那就太好了!

UPDATED更新

ODV doesn't allow me to do the customization I need though. ODV 不允许我做我需要的定制。 I would like to generate a plot like this where I can specify metadata variable to color the dots.我想像这样生成一个 plot ,我可以在其中指定元数据变量来为点着色。 To be more specific by the group_ID column in my data file seen in the example of my file below.更具体地说,通过我的数据文件中的 group_ID 列在下面的文件示例中看到。

Latitude    Longitude   Depth_m Sample_ID   Group_ID
49.7225 -42.4467    10  S1  1
49.7225 -42.4467    50  S2  1
49.7225 -42.4467    75  S3  1
49.7225 -42.4467    101 S4  1
49.7225 -42.4467    152 S5  1
49.7225 -42.4467    199 S6  1
46.312  -39.658 10  S7  2
46.312  -39.658 49  S8  2
46.312  -39.658 73  S9  2
46.312  -39.658 100 S10 2
46.312  -39.658 153 S11 2
46.312  -39.658 198 S12 2

Its been giving me a lot of trouble trying to figure it out though.它给我带来了很多麻烦试图弄清楚它。 I have calculated distance between coordinates using the haversine calculation but once I get there I am not sure how to use those distances to incorporate into a scatter plot.我已经使用半正弦计算计算了坐标之间的距离,但是一旦我到达那里,我不确定如何使用这些距离将这些距离合并到散点 plot 中。 This is what I have so far:这是我到目前为止所拥有的:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
#import haversine as hs
from math import radians
from sklearn.neighbors import DistanceMetric
df=pd.read_csv("locations.csv",sep="\t",index_col="Sample_ID")
#plt.scatter(df['Latitude'], df['Depth_m'])
#plt.show()
df['Latitude'] = np.radians(df['Latitude'])
df['Longitude'] = np.radians(df['Longitude'])
dist = DistanceMetric.get_metric('haversine')
x = dist.pairwise(np.unique(df[['Latitude','Longitude']].to_numpy(),axis=0))*6373
print(x)

This code lands me with a distance matrix for my coordinates but I honestly can't figure out how to take that and pull it in to a scatter plot that sets the x-axis from north to south.这段代码为我的坐标提供了一个距离矩阵,但老实说,我不知道如何把它拉到一个散点 plot 中,它将 x 轴从北到南设置。 Especially since there are multiple depths with the same coordinate that have to be accounted for.特别是因为必须考虑具有相同坐标的多个深度。 Any help plotting is much appreciated!非常感谢任何帮助绘图!

For the distance calculation you can to use the geopy package, specifically geopy.distance.geodesic() , to calculate the distance along an arc by assuming a particular ellipsoid (eg WGS84).对于距离计算,您可以使用geopy package,特别是geopy.distance.geodesic() ,通过假设特定的椭球体(例如 WGS84)来计算沿弧的距离。

To generate a plot similar to what you've described you can use the matplotlib library's scatterplot functionality, specifically matplotlib.pyplot.scatter() .要生成类似于您所描述的 plot ,您可以使用matplotlib库的散点图功能,特别是matplotlib.pyplot.scatter()

The code example below will step you through both the distance calculation (distance from some reference lat/long to another lat/long... this isn't necessarily the NS component but it's easy enough to calculate).下面的代码示例将引导您完成距离计算(从某个参考纬度/经度到另一个纬度/经度的距离......这不一定是 NS 组件,但它很容易计算)。 As well as how to generate the scatter plot using your Group_ID field to colour the points using two methods.以及如何使用 Group_ID 字段生成散点图 plot 以使用两种方法对点进行着色。

import matplotlib.pyplot as plt
import geopy
import pandas as pd

# Load your sample data to a Pandas DataFrame where each column corresponds to
# 'Latitude', 'Longitude', 'Depth_m', 'Sample_ID', 'Group_ID'
datafile = r'<path to a file containing your data>'
df = pd.read_csv(datafile)

# Defining one end of our arc to calculate distance along (arbitrarily taking 
# the first point in the example data as the reference point).
ref_point = (df['Latitude'].iloc[0], df['Longitude'].iloc[0])

#  Loop over each sample location calculating the distance along the arc using
#  pygeo.distance.geodesic function.
dist = []
for i in range(len(df)):
    cur_point = (df['Latitude'].iloc[i], df['Longitude'].iloc[i])
    cur_geodesic = geopy.distance.geodesic(ref_point, cur_point)
    cur_dist = cur_geodesic.km
    dist.append(cur_dist)

# Add computed distances to the df DataFrame as column 'Distance_km'
df['Distance_km'] = dist

# Create a matplotlib figure and add two axes for plotting
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)

# Example 1: of creating a scatter plot using the calculated distance field and
# colouring the points using a numeric field (i.e. Group_ID in this case is numeric)
pts = ax1.scatter(df['Distance_km'], df['Depth_m'], s=30, c=df['Group_ID'], cmap=plt.cm.jet)
plt.colorbar(pts, ax=ax1)

ax1.set_xlabel('Arc Distance from Reference Point (km)')
ax1.set_ylabel('Depth (m)')
ax1.set_title('Colouring Points by a Numeric Field')
ax1.invert_yaxis()
ax1.grid(True)

# Example of creating basically the same scatter plot as above but handling the
# case of non-numeric values in the field to be used for colour (e.g. imagine 
# wanting to the the Sample_ID field instead)
groups = list(set(df['Group_ID'])) # get a list of the unique Group_ID values
for gid in groups:
    df_tmp = df[df['Group_ID'] == gid]
    ax2.scatter(df_tmp['Distance_km'], df_tmp['Depth_m'], s=30, label=gid)
    
ax2.legend(loc='upper center', title='Legend')
ax2.set_xlabel('Arc Distance from Reference Point (km)')
ax2.set_ylabel('Depth (m)')
ax2.set_title('Colouring Points with Using Categorical Values')
ax2.invert_yaxis()
ax2.grid(True)

fig.tight_layout()
plt.show()

And the output figure...还有 output 图…… 在此处输入图像描述

I am not sure what you are trying to with distance, but conceptually you need to get your x output into your dataframe as a new column as I have done.In terms of having a different color for groups, I would use seaborn for this as they have a hue parameter.我不确定你想用距离做什么,但从概念上讲,你需要将你的 x output 放入你的 dataframe 作为一个新列,就像我所做的那样。就组的不同颜色而言,我会使用seaborn作为C50EA32A37901F27FD6他们有一个hue参数。 Please see the output below of your first scatterplot and an attempt at what you are trying to do with your second scatterplot:请参阅第一个散点图下方的 output 并尝试对第二个散点图执行的操作:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from math import radians
from sklearn.neighbors import DistanceMetric
import seaborn as sns
fig, ax = plt.subplots(nrows=2)
sns.scatterplot(data=df, x='Latitude', y='Depth_m', hue='Group_ID', ax=ax[0])
df['Latitude'] = np.radians(df['Latitude'])
df['Longitude'] = np.radians(df['Longitude'])
dist = DistanceMetric.get_metric('haversine')
df['Distance'] = (dist.pairwise(df[['Latitude','Longitude']].to_numpy())*6373)[0]
sns.scatterplot(data=df, x='Distance' , y='Depth_m', hue='Group_ID', ax=ax[1])
plt.show()

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM