Rendering a map under the grid on x-y plane in a 3D slice plot with python

Viewed 114

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.

3D plot

2D plot with map

enter image description here

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()
0 Answers
Related