Hello!
I’ve been trying to follow the trajectory of palaeo-coordinates (i.e. Scotese’s PaleoDEM coordinates) through time, e.g. from 540 Ma to 535, with Gplately/pygplates. This works without a hitch when Gplately/pygplates assigns the plate IDs, but something goes wrong when using pre-assigned plate IDs (edit: they end up in the wrong location as illustrated in the code/figures). I would like to use pre-assigned IDs as some coordinates do not fall on the plate polygons. If I let gplately. Points assign an ID, the coordinates that fall outside of the plates are either removed or incorrectly rotated.
I’ve managed to work out a partial fix that works if all coordinates fall on the plate polygons but ignores all coordinates that do not. This was done by manipulating the ‘features’ part of a gplately in the same way as if there would not have been a plate ID. The ‘features’ is probably where the problem is, and it might have something to do with coordinates incorrectly being specified to t = 0 Ma instead of t = 540 Ma. However, those are all big questions marks, and I’ve hit a wall.
Any help would be greatly appreciated!
I’ve deposited the code in a Dropbox folder along with the dataset with only continental coordinates, and a csv with all paleoDEM coordinates pre-assigned to a plate ID ( https://www.dropbox.com/scl/fo/e31nc0lx0uam58hggrtdr/h?rlkey=ysxuxm1owkns874u8wm87lx7i&dl=0 )
Cheers
Bouwe
### R code to run to start the interactive python session in Rstudio
# library(reticulate)
# library(tidyverse)
# use_condaenv("pygplates_py310")
# reticulate::repl_python()
# versions:
# python version 3.10.12
# pygplates 0.39
# gplately 1.0
# import packages
import pandas as pd
import numpy as np
import gplately
from gplately import pygplates
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
# load the plate model
gdownload = gplately.download.DataServer("Scotese2016")
rotation_model, topology_features, static_polygons = gdownload.get_plate_reconstruction_files()
coastlines, continents, COBs = gdownload.get_topology_geometries()
model = gplately.PlateReconstruction(rotation_model, topology_features, static_polygons)
gplot = gplately.PlotTopologies(model, coastlines=coastlines, continents=continents, COBs=COBs)
paleodem_A = pd.read_csv('Continental_coords_pID_assigned.csv')
# first use the pre-assigned plate IDs (I calculated these by with gplately.Points previously and saved the output)
gp = gplately.Points(plate_reconstruction=model, lons=paleodem_A['Longitude'], lats=paleodem_A['Latitude'], time=540, plate_id=paleodem_A['Plate_ID'])
# calculate lons and lats
rlons, rlats = gp.reconstruct(535, return_array=True)
# Set up a GeoAxis plot
fig = plt.figure(figsize=(32,24), dpi=600)
ax = fig.add_subplot(111, projection=ccrs.Mollweide(central_longitude = 0))
ax.set_global()
ax.gridlines(color='0.7',linestyle='--', xlocs=np.arange(-180,180,15), ylocs=np.arange(-90,90,15))
ax.set_title("Projected - plate ID specified")
# Plot shapefile features, subduction zones and MOR boundaries at 0 Ma
gplot.time = 540 # Ma
gplot.plot_coastlines(ax, color='DarkGrey')
sc = ax.scatter(paleodem_A['Longitude'], paleodem_A['Latitude'], color='orange',
transform=ccrs.PlateCarree(), label='A', s = 10)
sc = ax.scatter(rlons, rlats, color='blue',
transform=ccrs.PlateCarree(), label='Projected', s= 10)
ax.legend(frameon=False)
plt.show()
# now calculate the plate_ID with gplately.points
gp2 = gplately.Points(plate_reconstruction=model, lons=paleodem_A['Longitude'], lats=paleodem_A['Latitude'], time=540)
# all plate IDs are identical!
all(gp.plate_id == gp2.plate_id)
# all coords are identical!
all(gp.lats == gp2.lats)
all(gp.lons == gp2.lons)
# calculate the lons and lats by projecting into the future
rlons2, rlats2 = gp2.reconstruct(535, return_array=True)
# Set up a GeoAxis plot
fig = plt.figure(figsize=(32,24), dpi=600)
ax = fig.add_subplot(111, projection=ccrs.Mollweide(central_longitude = 0))
ax.set_global()
ax.gridlines(color='0.7',linestyle='--', xlocs=np.arange(-180,180,15), ylocs=np.arange(-90,90,15))
ax.set_title("Projected - plate ID not specified")
# Plot shapefile features, subduction zones and MOR boundaries at 0 Ma
gplot.time = 540 # Ma
gplot.plot_coastlines(ax, color='DarkGrey')
sc = ax.scatter(paleodem_A['Longitude'], paleodem_A['Latitude'], color='orange',
transform=ccrs.PlateCarree(), label='A', s = 10)
sc = ax.scatter(rlons2, rlats2, color='blue',
transform=ccrs.PlateCarree(), label='Projected', s= 10)
ax.legend(frameon=False)
plt.show()
# Now it does work....
# I looked at the code and I think the error is in the creation of the features, so recalculate as if plate_ID was absent
# create a 'features' object -> this is also what is created in the gplately.Points function when plate_ID is specified
features = gplately.tools.points_to_features(gp.lons, gp.lats, gp.plate_id)
# run the pygplates.partition_into_plates function to get the 'proper' features -> normally run in gplately.Points when plate_ID == None
partitioned_features = pygplates.partition_into_plates(
static_polygons, rotation_model, features, reconstruction_time=540, sort_partitioning_plates=None
)
# replace the original features
gp.features = partitioned_features
# calculate new coordinates
rlons3, rlats3 = gp.reconstruct(535, return_array=True)
# Set up a GeoAxis plot
fig = plt.figure(figsize=(32,24), dpi=600)
ax = fig.add_subplot(111, projection=ccrs.Mollweide(central_longitude = 0))
ax.set_global()
ax.gridlines(color='0.7',linestyle='--', xlocs=np.arange(-180,180,15), ylocs=np.arange(-90,90,15))
ax.set_title("Projected - features replaced")
# Plot shapefile features, subduction zones and MOR boundaries at 0 Ma
gplot.time = 540 # Ma
gplot.plot_coastlines(ax, color='DarkGrey')
sc = ax.scatter(paleodem_A['Longitude'], paleodem_A['Latitude'], color='orange',
transform=ccrs.PlateCarree(), label='A', s = 10)
sc = ax.scatter(rlons3, rlats3, color='blue',
transform=ccrs.PlateCarree(), label='Projected', s= 10)
ax.legend(frameon=False)
plt.show()
# and the calculated coordinates are now correct
# however this is problematic if I want to work with pre-assigned plate_IDs, especially if those do not fall on a continental shelve (as those will be changed to 0 with this fix)