I'm currently working on combining 2D contour plots to build a 3D plot in one figure. I would like to add a map under the x-y plane grid to visualize the dataset's position. Is this possible in some way? I wasn't able to come up with a solution myself. I'm currently using pyplot and cartopy. The first picture is the one where I'd like to add the map and the second one is a 2D version of the plot I want. I've also attached my code for the 3D plot but unfortunately I can't share the data. EDIT: I added a third picture that shows better what I'm looking for.
Code:
#---------------------------------------------------------------------------------------------
#required libraries
import json
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits import mplot3d as mpl
degree = u'\N{DEGREE SIGN}' #variable for degree sign
#lat 60 (55-78) data["lat"][0:60] OR [55, 56, 57, 58, 59, 60, 60.25, 60.5, 60.75, 61, 61.25, 61.5, 61.75, 62, 62.25, 62.5, 62.75, 63, 63.25, 63.5, 63.75, 64, 64.25, 64.5, 64.75, 65, 65.25, 65.5, 65.75, 66, 66.25, 66.5, 66.75, 67, 67.25, 67.5, 67.75, 68, 68.25, 68.5, 68.75, 69, 69.25, 69.5, 69.75, 70, 70.25, 70.5, 70.75, 71, 71.25, 71.5, 71.75, 72, 73, 74, 75, 76, 77, 78]
#alt 25 (800-25) [25, 50, 70, 90, 110, 130, 150, 170, 190, 210, 230, 250, 270, 290, 310, 330, 350, 370, 400, 450, 500, 550, 600, 700, 800]
#long 26 (10-35) list(range(10,36))
#---------------------------------------------------------------------------------------------
file = "file" #file name
with open(file) as f:
rawdata = json.load(f)
#setting up the coordinate system, parametres
latitude = rawdata["lat"][0:60] #latitude
altitude = [25, 50, 70, 90, 110, 130, 150, 170, 190, 210, 230, 250, 270, 290, 310, 330, 350,
370, 400, 450, 500, 550, 600, 700, 800] #altitude
longitude = list(range(10,36))
altitude.reverse() #must be reversed because of the data structure in the json-file
longitude_list = [10, 20, 30] #give the longitudes you want to plot in accending order between
10 and 35 degrees (integers only)
#function for creating the data matrices for contour plots for a given longitude
def ne_long(long, x, y, data): #longitude, latitude, altitude, ne-data
z = np.zeros((len(y), len(x))) #ne (electron denstiy) data matrix
#list the indices of the vectors that correspond to the given longitude to index_list
index_list = []
for i in range(len(data["long"])):
if data["long"][i] == long:
index_list.append(i)
#check that the given set value is suitable
if len(index_list) == 0:
print("given value not suitable")
raise ValueError
#create the data matrix for electron density from the data using the index_list
index = 0
for y_index in range(len(y)):
if index > 1500:
print("stop1")
break
for x_index in range(len(x)):
if index > 1500:
print("stop2")
break
z[y_index, x_index] = data["ne"][index_list[index]]
index += 1
return z
#function for creating a data matrix for a contour plot for a given latitude
def ne_lat(lat, x, y, data): #latitude, longitude, altitude, ne-data
z = np.zeros((len(y), len(x))) #ne (electron denstiy) data matrix
#list the indices of the vectors that correspond to the given latitude to index_list
index_list = []
for i in range(len(data["lat"])):
if data["lat"][i] == lat:
index_list.append(i)
#check that the given set value is suitable
if len(index_list) == 0:
print("given value not suitable")
raise ValueError
#create the data matrix for by picking the right elements from the data using the index_list
index = 0
for x_index in range(len(x)):
if index > 2000:
print("stop")
break
for y_index in range(len(y)):
if index > 2000:
print("stop")
break
z[y_index, x_index] = data["ne"][index_list[index]]
index += 1
return z
#data matrices to a list
zz = [ ne_long(l, latitude, altitude, rawdata) for l in longitude_list]
#rendering the plot
xx, yy = np.meshgrid(latitude, altitude)
XX, YY= np.meshgrid(longitude, altitude)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection="3d")
ax.contourf(ne_lat(78, longitude, altitude, rawdata), XX, YY, zdir="x", levels=20, offset = 80, alpha = 0.6)
C = ax.contourf(xx, zz[0], yy, zdir="y", offset=longitude_list[0], alpha = 0.98, levels = 20)
if len(longitude_list) > 1:
for ll in range(1, len(longitude_list)):
ax.contourf(xx, zz[ll], yy, zdir="y", offset=longitude_list[ll], alpha = 0.98-0.1*ll, levels = 20)
ax.set_xlim3d(80,55)
ax.set_zlim3d(0, 800)
ax.set_ylim3d(10, 40)
ax.view_init(40, 40)
ax.set_xlabel(f"Latitude ({degree})")
ax.set_zlabel("Altitude (km)")
ax.set_ylabel(f"Longitude ({degree})")
plt.colorbar(C, label="Electron density " + r"$(10^{11}/m^3 )$")
plt.show()
