[Python] Dessinez des données d'altitude sur une surface sphérique avec Plotly et dessinez un globe qui peut être tourné en rond et en rond

introduction

Il prend en charge divers langages, y compris Python, et vous pouvez utiliser Plotly, qui vous permet de dessiner des diagrammes interactifs relativement facilement et d'utiliser les données d'altitude pour faire une rotation comme Google Earth. Créons un globe.

Le résultat ressemble à ceci. https://rkiuchir.github.io/3DSphericalTopo

EarthGlove.gif

3 points

  1. Acquisition et lecture des données d'élévation
  2. Convertissez les informations de latitude et de longitude exprimées dans le système de coordonnées orthogonales en système de coordonnées sphériques ([Plotly Chart Studio: Heatmap plot on a spherical map](https://chart-studio.plotly.com/~empet/14813/heatmap] -voir un tracé sur une carte sphérique / # /))
  3. Dessiner avec Plotly

Environnement d'exécution

0. Installer tracé

Il peut être installé avec pip install plotly.

1-1. Acquisition des données d'altitude

1-2. Lecture des données d'altitude

Tout d'abord, lisez les trois données de latitude / longitude et d'altitude du fichier de données au format netCDF.

Concernant la résolution, les données sont ignorées selon la valeur de résolution spécifiée.

import numpy as np
from netCDF4 import Dataset

def Etopo(lon_area, lat_area, resolution):
    ### Input
    # resolution: resolution of topography for both of longitude and latitude [deg]
    # (Original resolution is 0.0167 deg)
    # lon_area and lat_area: the region of the map which you want like [100, 130], [20, 25]
    ###
    

    ### Output
    # Mesh type longitude, latitude, and topography data
    ### 

    # Read NetCDF data
    data = Dataset("ETOPO1_Ice_g_gdal.grd", "r")
    
    # Get data
    lon_range = data.variables['x_range'][:]
    lat_range = data.variables['y_range'][:]
    topo_range = data.variables['z_range'][:]
    spacing = data.variables['spacing'][:]
    dimension = data.variables['dimension'][:]
    z = data.variables['z'][:]

    lon_num = dimension[0]
    lat_num = dimension[1]
    
    # Prepare array
    lon_input = np.zeros(lon_num); lat_input = np.zeros(lat_num)
    for i in range(lon_num):
        lon_input[i] = lon_range[0] + i * spacing[0]

    for i in range(lat_num):
        lat_input[i] = lat_range[0] + i * spacing[1]

    # Create 2D array
    lon, lat = np.meshgrid(lon_input, lat_input)

    # Convert 2D array from 1D array for z value
    topo = np.reshape(z, (lat_num, lon_num))

    # Skip the data for resolution
    if ((resolution < spacing[0]) | (resolution < spacing[1])):
        print('Set the highest resolution')
    else:
        skip = int(resolution/spacing[0])
        lon = lon[::skip,::skip]
        lat = lat[::skip,::skip]
        topo = topo[::skip,::skip]

    topo = topo[::-1]

    # Select the range of map
    range1 = np.where((lon>=lon_area[0]) & (lon<=lon_area[1]))
    lon = lon[range1]; lat = lat[range1]; topo = topo[range1]
    range2 = np.where((lat>=lat_area[0]) & (lat<=lat_area[1]))
    lon = lon[range2]; lat = lat[range2]; topo = topo[range2]
    
    # Convert 2D again
    lon_num = len(np.unique(lon))
    lat_num = len(np.unique(lat))
    lon = np.reshape(lon, (lat_num, lon_num))
    lat = np.reshape(lat, (lat_num, lon_num))
    topo = np.reshape(topo, (lat_num, lon_num))
   
    return lon, lat, topo

2. Convertissez les informations de latitude et de longitude en coordonnées sphériques

(Voir Plotly Chart Studio: tracé Heatmap sur une carte sphérique)

Ici, les informations de latitude et de longitude exprimées par les coordonnées du système orthogonal préparées ci-dessus sont converties en système de coordonnées sphériques.

def degree2radians(degree):
    # convert degrees to radians
    return degree*np.pi/180

def mapping_map_to_sphere(lon, lat, radius=1):
    #this function maps the points of coords (lon, lat) to points onto the  
    sphere of radius radius
    
    lon=np.array(lon, dtype=np.float64)
    lat=np.array(lat, dtype=np.float64)
    lon=degree2radians(lon)
    lat=degree2radians(lat)
    xs=radius*np.cos(lon)*np.cos(lat)
    ys=radius*np.sin(lon)*np.cos(lat)
    zs=radius*np.sin(lat)
    return xs, ys, zs

3. Dessiner avec Plotly

Maintenant, dessinons en fait les données tridimensionnelles de latitude, longitude et altitude représentées par le système de coordonnées sphériques dans Plotly.

Tout d'abord, appelez la fonction préparée en 1-2. Pour lire les données d'altitude globales. Si vous le lisez avec une résolution trop élevée, la quantité de données sera importante de l'ordre du cube, donc cette fois la résolution est réglée à 0,8 °.

# Import topography data
# Select the area you want
resolution = 0.8
lon_area = [-180., 180.]
lat_area = [-90., 90.]

# Get mesh-shape topography data
lon_topo, lat_topo, topo = ReadGeo.Etopo(lon_area, lat_area, resolution)

Ensuite, convertissez-le en système de coordonnées sphériques avec la fonction préparée en 2.

xs, ys, zs = mapping_map_to_sphere(lon_topo, lat_topo)

Et à partir de là, nous passerons réellement au dessin.

Tout d'abord, définissez l'échelle de couleurs utilisée pour dessiner les données d'élévation.

# Import color scale
import Plotly_code as Pcode
name = "topo"
Ctopo = Pcode.Colorscale_Plotly(name)
cmin = -8000
cmax = 8000

Ensuite, dessinez en utilisant Plotly. Ici, vous entrez les données d'entrée et l'échelle de couleurs.

topo_sphere=dict(type='surface',
            x=xs, 
            y=ys, 
            z=zs,
            colorscale=Ctopo,
            surfacecolor=topo,
            cmin=cmin, 
            cmax=cmax)
            )

Effacez l'arbre, etc. pour qu'il soit beau.

noaxis=dict(showbackground=False,
            showgrid=False,
            showline=False,
            showticklabels=False,
            ticks='',
            title='',
            zeroline=False)

Enfin, utilisez la mise en page pour spécifier le titre et la couleur d'arrière-plan. Cette fois, la couleur de fond est noire, avec un peu de conscience de Google Earth.


import plotly.graph_objs as go

titlecolor = 'white'
bgcolor = 'black'

layout = go.Layout(
      autosize=False, width=1200, height=800,
      title = '3D spherical topography map',
      titlefont = dict(family='Courier New', color=titlecolor),
      showlegend = False,
      scene = dict(
        xaxis = noaxis,
        yaxis = noaxis,
        zaxis = noaxis,
        aspectmode='manual',
        aspectratio=go.layout.scene.Aspectratio(
            x=1, y=1, z=1)),
        paper_bgcolor = bgcolor,
        plot_bgcolor = bgcolor)

Ensuite, dessinez en utilisant celui préparé (ici, sortie html).

from plotly.offline import plot

plot_data=[topo_sphere]

fig = go.Figure(data=plot_data, layout=layout)
plot(fig, validate = False, filename='3DSphericalTopography.html', 
     auto_open=True)

en conclusion

Avec cela, je pense que je pourrais dessiner un tracé d'un globe qui peut être tourné comme au début. Je l'utilise en superposant la distribution des tremblements de terre en plus de cela.

Cet exemple peut être facilement appliqué lors du traçage sur une sphère, et je pense qu'il a un large éventail d'utilisations. De plus, il est utile non seulement pour les données d'altitude, mais aussi pour créer une carte en deux dimensions, et il est également possible de dessiner des images en trois dimensions qui expriment la hauteur avec des données d'altitude.

Recommended Posts

[Python] Dessinez des données d'altitude sur une surface sphérique avec Plotly et dessinez un globe qui peut être tourné en rond et en rond
[Python] Créez un graphique qui peut être déplacé avec Plotly
Obtenez des données de VPS MySQL avec Python 3 et SQL Alchemy
J'ai fait un shuffle qui peut être réinitialisé (inversé) avec Python
Créez un graphique des devises qui peut être déplacé avec Plotly (2)
Créez un graphique des devises qui peut être déplacé avec Plotly (1)
Comprendre les probabilités et les statistiques qui peuvent être utilisées pour la gestion des progrès avec un programme python
Un mémo contenant Python2.7 et Python3 dans CentOS
Créez une application Web qui peut être facilement visualisée avec Plotly Dash
Folium: Visualisez les données sur une carte avec Python
Formatez les données DataFrame avec Pytorch sous une forme pouvant être entraînée avec NN
Article qui peut être une ressource humaine qui comprend et maîtrise le mécanisme de l'API (avec du code Python)
Notes sur les connaissances Python utilisables avec AtCoder
Un serveur qui fait écho aux données POSTées avec flask / python
Installez Mecab et CaboCha sur ubuntu16.04LTS afin qu'il puisse être utilisé à partir de la série python3
[Python] Un programme pour trouver le nombre de pommes et d'oranges qui peuvent être récoltées
Un mémo qui lit les données de dashDB avec Python et Spark
Faisons un diagramme sur lequel on peut cliquer avec IPython
J'ai acheté et analysé la loterie jumbo de fin d'année avec Python qui peut être exécutée dans Colaboratory
J'ai essayé d'utiliser "Asciichart Py" qui peut dessiner un beau graphique sur la console avec Python.
[Python] Un programme qui trouve le nombre maximum de jouets pouvant être achetés avec votre argent
J'ai fait un package qui peut comparer des analyseurs morphologiques avec Python
Créez un environnement Python 2.7 64 bits avec TDM-GCC et MinGW-w64 sous Windows 7
Transformez plusieurs données numériques d'élévation en une seule image avec Python
Créez un environnement Python sur votre Mac avec Anaconda et PyCharm
Créez une Spinbox qui peut être affichée en binaire avec Tkinter
Dessinez une illusion d'aquarelle avec détection des contours en Python3 et openCV3
Créez une Spinbox pouvant être affichée dans HEX avec Tkinter
Module standard Python utilisable en ligne de commande
Un script python qui supprime les fichiers ._DS_Store et ._ * créés sur Mac
Une histoire et sa mise en œuvre selon laquelle des données arbitraires a1 * a2 peuvent être représentées par un réseau de neurones ReLU à 3 couches avec des neurones intermédiaires a1 et a2 sans erreur.
J'ai écrit un tri-arbre qui peut être utilisé pour l'implémentation de dictionnaire à grande vitesse en langage D et Python
Puis-je être un data scientist?
[Python] Code qui peut être écrit avec la mort cérébrale au début lors du scraping en tant que débutant
Obtenez une liste des paramètres de caméra qui peuvent être définis avec cv2.VideoCapture et faites-en un type de dictionnaire
La barre de données EXCEL et l'échelle de couleurs peuvent également être faites avec des pandas
J'ai créé un modèle de projet Python générique
[Python] Un programme qui trouve une paire qui peut être divisée par une valeur spécifiée
Optimisation mathématique pour un travail gratuit avec Python + PuLP
Comment dessiner une ligne verticale sur une carte de chaleur dessinée avec Python Seaborn
Envoyer et recevoir des données binaires via une communication série avec python3 (sur Mac)
Créez un environnement Python 3 avec pyenv sur Mac et affichez des graphiques Network X
Créez un arbre de décision à partir de 0 avec Python et comprenez-le (4. Structure des données)
J'ai fait un module PyNanaco qui peut charger des crédits nanaco avec python
Je voulais créer rapidement un serveur de messagerie utilisable librement avec postfix + dovecot sur EC2
[Python] Création d'un outil qui peut lister, sélectionner et exécuter des fichiers python avec tkinter et à propos de la partie qui a été interceptée
[Python] Un programme qui crée des escaliers avec #
Carte des informations de location sur une carte avec python
Un monde typé qui commence par Python
Notes pour créer des figures pouvant être publiées dans des revues avec matplotlib
Classe pour PYTHON qui peut être utilisée sans connaître LDAP
Je souhaite créer une file d'attente prioritaire pouvant être mise à jour avec Python (2.7)
J'ai enregistré PyQCheck, une bibliothèque qui peut effectuer QuickCheck avec Python, dans PyPI.
Déplacement de Raspberry Pi à distance afin qu'il puisse être connecté à une LED avec Python
Construisez un environnement Python + bouteille + MySQL avec Docker sur RaspberryPi3! [Essai et erreur]
Puisque python est lu comme "Pichon", il peut être exécuté avec "Pichon" (c'est une histoire)