[Python] I want to make a 3D scatter plot of the epicenter with Cartopy + Matplotlib!

One of the features of Matplotlib is that it is very easy to draw a 3D graph. Taking advantage of this feature, I tried to draw a 3D scatter plot of the epicenter with the map displayed in the map library Cartopy.

1. Table of contents

1. Table of Contents 2. Purpose of this page 3. Usage environment 4. How to put a map into a 3D graph 5. Demonstration 6. Conclusion 7. References

2. Purpose of this page

After plotting the three-dimensional position of the epicenter, draw a map at a depth of 0 km.

3. Usage environment

4. How to put a map into a 3D graph

Now, Cartopy doesn't really support 3D plotting in Matplotlib. Therefore, in order to display it on a 3D plot, it is necessary to convert it to some format supported by Matplotlib. Here, we will focus on the format called Collection.

There is precedent in stackoverflow for the basic method. User pelson answers the question "contourf in 3D Cartopy" of user mtb-za, and the script on this page also refers to this. However, as pointed out on the same site, pelson's answer gives an error. This time around, we're outsmarting an ad hoc solution.

The script that pelson answered basically has the following flow.

--Specify the feature to draw from Cartopy --Get only geometry from feature --Convert geometry to the projection you want to draw (here equirectangular projection) --Get the drawing range from the axes of the matplotlib you are drawing and apply the method of intersection between this and the intersecting geometry. --Convert geometry to path --Convert path to polygon --Convert polygon to collection

However, when I make an intersection, I get an error that some geometry is invalid. Imagine that some of the line segments that make up geometry intersect each other. This doesn't work for the script, so I've inserted code before the intersection to eliminate the invalid geometry. It looks like the result is not a problem (I haven't tracked what happens in other areas and projections).

5. Demonstration

The beginning of the data used is as follows.

temp.csv


longitude	latitude	depth	strike1	dip1	rake1	strike2	dip2	rake2	mantissa	exponent	type
136.3025	36.2495	11	63	59	94	236	31	84	2.66	21	1
135.5475	35.2028	20	334	85	11	243	79	175	9.92	21	2
136.72	    35.1692	14	3	70	105	145	25	55	3.43	21	1
134.8153	34.4015	11	293	87	28	201	62	177	4.23	21	2

Of these, the type of fault determined from the longitude, latitude, depth, and direction of the principal stress axis is used for drawing.

cartopy_3d.py



import itertools
import pandas as pd
import cartopy.feature
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from cartopy.mpl.patch import geos_to_path
from matplotlib.collections import PolyCollection
 
mfile = pd.read_csv("temp.csv") #data
loc = mfile[["longitude", "latitude", "depth"]]
typ = mfile[["type"]] #Is it a normal fault type? 0=Normal fault, 1 =Reverse fault, 2 =Strike-slip fault
pallet = ["blue", "red", "lime"] #Color coded by fault type

pallet_list = [] #List colors
for i in range(len(typ)) :
    pallet_list.append(pallet[int(typ.iloc[i,0])])

#Main plot
fig = plt.figure()
ax3d = fig.add_subplot(111, projection='3d')
#Specifying the area
ax3d.set_xlim(134.0,137.0)
ax3d.set_ylim(33.5,36.5)
ax3d.set_zlim(25,0)
#label
ax3d.set_xlabel("longitude")
ax3d.set_ylabel("latitude")
ax3d.set_zlabel("depth")
#Scatter plot
ax3d.scatter(loc["longitude"],loc["latitude"],loc["depth"],"o", c=pallet_list,s=10,depthshade=0)

#Set axis for map
proj_ax = plt.figure().add_subplot(111, projection=ccrs.PlateCarree())
proj_ax.set_xlim(ax3d.get_xlim())
proj_ax.set_ylim(ax3d.get_ylim())
# a usefull function
concat = lambda iterable: list(itertools.chain.from_iterable(iterable))
#Get geometry
target_projection = proj_ax.projection
feature = cartopy.feature.NaturalEarthFeature('physical', 'land', '10m')
geoms = feature.geometries()
#Area acquisition
boundary = proj_ax._get_extent_geom()
#Projection method conversion
geoms = [target_projection.project_geometry(geom, feature.crs) for geom in geoms]

#Elimination of invalid geometry
geoms2 = []
for i in range(len(geoms)) :
    if geoms[i].is_valid :
        geoms2.append(geoms[i])

geoms = geoms2

# intersection
geoms = [boundary.intersection(geom) for geom in geoms]
# geometry to path to polygon to collection
paths = concat(geos_to_path(geom) for geom in geoms)
polys = concat(path.to_polygons() for path in paths)
lc = PolyCollection(polys, edgecolor='black', facecolor='green', closed=True, alpha=0.2)

#Insert
ax3d.add_collection3d(lc, zs=0)
ax3d.view_init(elev=30, azim=-120)
plt.close(proj_ax.figure) #If not closed plt.Two come out in show
fig.savefig("sample2.png ")
plt.show() 
#plt.close(fig)

Display result window.png

By the way, if you do not intersect, the map will protrude from the drawing area.

6. Conclusion

What did you think. It's fun to move the 3D plot with the mouse (laughs). Other projection methods are also described on the official website of Cartopy, so please use them.

7. References

--National Research Institute for Earth Science and Disaster Prevention Broadband Seismic Observation Network (F-net) Search for Mechanism Solutions
https://www.fnet.bosai.go.jp/event/search.php?LANG=ja

Recommended Posts

[Python] I want to make a 3D scatter plot of the epicenter with Cartopy + Matplotlib!
I want to make a game with Python
[Python] How to draw a scatter plot with Matplotlib
I want to output the beginning of the next month with Python
I wanted to solve the ABC164 A ~ D problem with Python
[Introduction] I want to make a Mastodon Bot with Python! 【Beginners】
I want to make matplotlib a dark theme
Create 3D scatter plot with SciPy + matplotlib (Python)
I want to write to a file with Python
(Memorandum) Make a 3D scatter plot with matplodlib
[Python] If you want to draw a scatter plot of multiple clusters
Python: I want to measure the processing time of a function neatly
I tried to make a simple mail sending application with tkinter of Python
I want to inherit to the back with python dataclass
I wanted to visualize 3D particle simulation with the Python visualization library Matplotlib.
I want to work with a robot in python.
[Python] I want to make a nested list a tuple
I want to manually create a legend with matplotlib
Draw a line / scatter plot on the CSV file (2 columns) with python matplotlib
[Python] How to create a 2D histogram with Matplotlib
I want to solve the problem of memory leak when outputting a large number of images with Matplotlib
I want to run a quantum computer with Python
I tried to make something like a chatbot with the Seq2Seq model of TensorFlow
I want to plot the location information of GTFS Realtime on Jupyter! (With balloon)
[Mac] I want to make a simple HTTP server that runs CGI with Python
I tried to find the entropy of the image with python
I want to specify another version of Python with pyvenv
I want to make a blog editor with django admin
I want to start a lot of processes from python
I want to make a click macro with pyautogui (desire)
I want to make a click macro with pyautogui (outlook)
[Python] I want to use the -h option with argparse
I want to know the features of Python and pip
I want to make input () a nice complement in python
I want to debug with Python
Make a note of what you want to do in the future with Raspberry Pi
I want to see the graph in 3D! I can make such a dream come true.
I want to output a beautifully customized heat map of the correlation matrix. matplotlib edition
I wrote a doctest in "I tried to simulate the probability of a bingo game with Python"
How to plot a lot of legends by changing the color of the graph continuously with matplotlib
I want to make a voice changer using Python and SPTK with reference to a famous site
[5th] I tried to make a certain authenticator-like tool with python
I want to use a wildcard that I want to shell with Python remove
[2nd] I tried to make a certain authenticator-like tool with python
I tried to make a regular expression of "amount" using Python
I tried to make a regular expression of "time" using Python
[3rd] I tried to make a certain authenticator-like tool with python
[Introduction to StyleGAN] I played with "The Life of a Man" ♬
I tried to create a list of prime numbers with python
I tried to make a regular expression of "date" using Python
I want to do a full text search with elasticsearch + python
I tried to make a periodical process with Selenium and Python
I tried to make a 2channel post notification application with Python
I tried to make a todo application using bottle with python
[4th] I tried to make a certain authenticator-like tool with python
I want to check the position of my face with OpenCV!
[1st] I tried to make a certain authenticator-like tool with python
I tried to improve the efficiency of daily work with Python
I tried to make a mechanism of exclusive control with Go
I want to build a Python environment
I want to analyze logs with Python