Можно ли искажать или манипулировать точками на графике matplotlib?
У меня есть приложение для прямой видимости, которое использует данные высоты из API Google возвышения, однако это отображает только «плоскую землю». Можно ли исказить или исказить мои показания, чтобы имитировать кривизну земли? Если так, как я могу применить это к своему коду? Я заранее прошу прощения, поскольку математика не является моей сильной стороной, и я все еще довольно новичок в кодировании.
import csv
import math
import urllib.request
import json
import matplotlib.pyplot as plt
import time
import polyline
##Extract data from radar and turbine csv files##
def generate_elevation(folderoutput):
with open('../inputdata/radars.csv') as csvfile: #get radar data
reader = csv.reader(csvfile, delimiter=',')
for row in reader:
#START-END POINT
P1=[]
P2=[]
radarlong=(float(row[0])) #convert to correct data types
radarlat=(float(row[1]))
radarheight=(float(row[2]))
radarname=(row[3])
radarlong=(radarlong)
radarlat=(radarlat)
P1.append(radarlong)
P1.append(radarlat)
##Open windfarm csv and store variables
with open('../inputdata/windfarms.csv') as csvfile: #get windfarm data
reader = csv.reader(csvfile, delimiter=',')
for row in reader:
windfarmlong = (float(row[0])) #convert to correct data types
windfarmlat = (float(row[1]))
windfarmheight = (float(row[2]))
windfarmname = (row[3])
P2=[windfarmlong, windfarmlat]
print(P1, P2)
#NUMBER OF POINTS
s=200
interval_lat=(P2[0]-P1[0])/s #interval for latitude
interval_lon=(P2[1]-P1[1])/s #interval for longitude
#SET A NEW VARIABLE FOR START POINT
lat0=P1[0]
lon0=P1[1]
#LATITUDE AND LONGITUDE LIST
lat_list=[lat0]
lon_list=[lon0]
print("Generating path")
#GENERATING POINTS
for i in range(s):
lat_step=lat0+interval_lat
lon_step=lon0+interval_lon
lon0=lon_step
lat0=lat_step
lat_list.append(lat_step)
lon_list.append(lon_step)
print("Path Generated")
#HAVERSINE FUNCTION
def haversine(lat1,lon1,lat2,lon2):
lat1_rad=math.radians(lat1)
lat2_rad=math.radians(lat2)
lon1_rad=math.radians(lon1)
lon2_rad=math.radians(lon2)
delta_lat=lat2_rad-lat1_rad
delta_lon=lon2_rad-lon1_rad
a=math.sqrt((math.sin(delta_lat/2))**2+math.cos(lat1_rad)*math.cos(lat2_rad)*(math.sin(delta_lon/2))**2)
d=2*6371000*math.asin(a)
return d
print("Calculating distance")
#DISTANCE CALCULATION
d_list=[]
for j in range(len(lat_list)):
lat_p=lat_list[j]
lon_p=lon_list[j]
dp=haversine(lat0,lon0,lat_p,lon_p)/1000 #km
dp=dp*0.539957 #convert km to nm
d_list.append(dp)
d_list_rev=d_list[::-1] #reverse list
print("Distance calculated")
#CONSTRUCT URL
path=[]
for i in range(len(lat_list)):
toAdd=(lat_list[i],lon_list[i])
path.append(toAdd)
#Encode to polyline
polystring = polyline.encode(path, 5)
try:
print("Sending request")
#SEND REQUEST
api_key='insert your key here'
url='https://maps.googleapis.com/maps/api/elevation/json?locations=enc:' + polystring + api_key
response = urllib.request.Request(url,headers={'Content-Type': 'application/json'})
fp=urllib.request.urlopen(response)
#RESPONSE PROCESSING
res_byte=fp.read()
res_str=res_byte.decode("utf8")
js_str=json.loads(res_str)
#print (js_mystr)
fp.close()
print("Processing response")
#GETTING ELEVATION
response_len=len(js_str['results'])
elev_list=[]
for j in range(response_len):
elev_list.append(js_str['results'][j]['elevation'])
startLOS = elev_list[0] + radarheight
endLOS = elev_list[-1] + windfarmheight
#BASIC STAT INFORMATION
mean_elev=round((sum(elev_list)/len(elev_list)),3)
min_elev=min(elev_list)
max_elev=max(elev_list)
distance=d_list_rev[-1]
print("Plotting line of sight profile")
#PLOT ELEVATION PROFILE
base_reg=0
plt.figure(figsize=(10,4))
plt.plot(d_list_rev,elev_list)
plt.plot([0,distance],[min_elev,min_elev],'--g',label='min: '+str(min_elev)+' m')
plt.plot([0,distance],[max_elev,max_elev],'--r',label='max: '+str(max_elev)+' m')
plt.plot([0,distance],[mean_elev,mean_elev],'--y',label='ave: '+str(mean_elev)+' m')
plt.plot([0,distance],[startLOS, endLOS])##line of sight line
plt.fill_between(d_list_rev,elev_list,base_reg,alpha=0.1)
plt.text(d_list_rev[0],elev_list[0],radarname)
plt.text(d_list_rev[-1],elev_list[-1],windfarmname)
plt.xlabel("Distance(Nm)")
plt.ylabel("Elevation(m)")
plt.grid()
plt.legend(fontsize='small')
print('Saving...')
filename= radarname + windfarmname
##Save the graph
plt.savefig(folderoutput + '/' + ' ' + filename)
plt.close()
print(filename + ' ' + 'saved...')
time.sleep(3)
except Exception as e:
print(str(e))
if __name__ == "__main__":
generate_elevation('../lineofsight_graphs')
код выше создает следующее изображение, используя matplotlib
В качестве альтернативы есть ли обходной путь для «имитации» изгиба линии визирования в этом случае?