Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tutorial: Adding a data set on top of a topographic surface via "drapegrid" of "Figure.grdview" #3316

Merged
merged 61 commits into from
Sep 2, 2024

Conversation

yvonnefroehlich
Copy link
Member

@yvonnefroehlich yvonnefroehlich commented Jul 7, 2024

Description of proposed changes

It would be nice to have a gallery example showing the usage of the drapegrid parameter of pygmt.Figure.grdview for adding a data set on top of a topographic surface.

So far I started working on two different ideas / examples in parallel:

  1. A grid as xarray.DataArray
    • Using two different remote datasets; one for the elevation and another one for the color-coding
  2. An image [grid] as netCDF file
    • Modified from GMT example 32; however, some of the used GMT modules are not available in PyGMT yet

At the momentan I am not 100 % happy with both examples - some aspects:

  • Probably one example should be enough to show the principle usage
  • In case we keep both / two examples, maybe change the region of 1. to something interesting outside of Europe
  • Colormap for curstal age - SCM by F. Crameri vs. built-in by GMT
  • Creation of netCDF file for 2. not directly possible in PyGMT as grdconvert and grdedit are not wrapped yet; other method to do this in Python

TODO

  • account aspect ratio of image via argument passed to the region parameter
  • z values for plotting elements on top of topography (symbols, text, coastlines, land)

Preview
https://pygmt-dev--3316.org.readthedocs.build/en/3316/tutorials/advanced/draping_on_3d_surface.html

Reminders

  • Run make format and make check to make sure the code follows the style guide.
  • Add tests for new features or tests that would have caught the bug that you're fixing.
  • Add new public functions/methods/classes to doc/api/index.rst.
  • Write detailed docstrings for all functions/methods.
  • If wrapping a new module, open a 'Wrap new GMT module' issue and submit reasonably-sized PRs.
  • If adding new functionality, add an example to docstrings or tutorials.
  • Use underscores (not hyphens) in names of Python files and directories.

Slash Commands

You can write slash commands (/command) in the first line of a comment to perform
specific operations. Supported slash command is:

  • /format: automatically format and lint the code

@yvonnefroehlich yvonnefroehlich added the documentation Improvements or additions to documentation label Jul 7, 2024
@yvonnefroehlich yvonnefroehlich added this to the 0.13.0 milestone Jul 7, 2024
@yvonnefroehlich
Copy link
Member Author

/format

@yvonnefroehlich
Copy link
Member Author

/format

@yvonnefroehlich yvonnefroehlich self-assigned this Jul 21, 2024
@seisman
Copy link
Member

seisman commented Jul 22, 2024

  • Creation of netCDF file for 2. not directly possible in PyGMT as grdconvert and grdedit are not wrapped yet; other method to do this in Python

Actually, it's possible to read the PNG into an xarray.DataArray object and pass it directly to grdview:

import rasterio
import xarray as xr

with rasterio.open("https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Flag_of_Europe.svg/1000px-Flag_of_Europe.svg.png") as dataset:
    data = dataset.read()
    drapegrid = xr.DataArray(data, dims=("band", "y", "x"))

and then change drapegrid="@euflag.nc" to drapegrid=drapegrid

@seisman
Copy link
Member

seisman commented Jul 22, 2024

  • Probably one example should be enough to show the principle usage

I prefer two have two examples, one for draping a grid and another for draping an image. They're slightly different that the first one need a CPT file and the 2nd one doesn't.

@yvonnefroehlich
Copy link
Member Author

yvonnefroehlich commented Jul 28, 2024

Actually, it's possible to read the PNG into an xarray.DataArray object and pass it directly to grdview

Thanks, @seisman! That's nice, and actually not too difficult. I should definitely work on my xarray knowledge!

I prefer two have two examples, one for draping a grid and another for draping an image. They're slightly different that the first one need a CPT file and the 2nd one doesn't.

I thought about having examples for both draping a grid and draping an image, but then I faced the problem with loading the PNG file. But it can be solved by using rasterio and xarray. I am wondering if it makes sense to make this a tutorial, as the script is a bit longer when keeping both examples, but also totally fine with keeping this a "normal" gallery example?

@seisman
Copy link
Member

seisman commented Jul 29, 2024

A tutorial is OK to me.

@yvonnefroehlich yvonnefroehlich changed the title POC / WIP: Gallery example: Adding a data set on top of a topographic surface via "drapegrid" of "Figure.grdview" WIP: Tutorial: Adding a data set on top of a topographic surface via "drapegrid" of "Figure.grdview" Jul 29, 2024
# the stars (value 255 -> upper half)
pygmt.makecpt(cmap="0/51/153,255/204/0", series=[0, 256, 128])

fig.grdview(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you forget zsize here?

Copy link
Member Author

@yvonnefroehlich yvonnefroehlich Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the zsize parameter (temporarily), as I have not figured out yet, how to adjust the position of the following plotting elements (added via coast, plot, text) corresponding to the value of zsize:

no zsize zsize="1c"
flag_0c flag_1c
zsize="1.5c" zsize="2c"
flag_1 5c flag_2c

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For points, plot3d is needed. For coastlines, it's likely we need to dump the coastlines and the use grdtrack to determine the z-value for each data points and then pass them to plot3d.

Comment on lines 135 to 177
# %%
# Additionally we can plot some features like coastlines, symbols, and text on top of
# the map. Setting ``perspective=True`` leads to the same azimuth and elevation values
# as we passed to the ``perspective`` parameter of :meth:`pygmt.Figure.grdview`.

# Plot water masses, political broders, and shorelines
fig.coast(
water="white@50",
borders="1/1p,lightgray",
shorelines="1/0.5p,gray30",
perspective=True,
)

# Set up a pandas.DataFrame with coordinates and names of three cities
cities = pd.DataFrame(
{
"longitude": [7.10, 4.35, 5.69], # degrees East
"latitude": [50.73, 50.85, 50.85], # degress North
"elevation": [60, 13, 49], # meters
"name": ["Bonn", "Bruxelles", "Maastricht"],
}
)
# Plot markers
fig.plot3d(
x=cities.longitude,
y=cities.latitude,
z=cities.elevation,
style="s0.3c", # Use squares with a size of 0.3 centimeters
pen="1.5p,white",
fill="black",
perspective=True,
)
# Add labels
fig.text(
x=cities.longitude,
y=cities.latitude,
text=cities.name,
justify="TL", # Use Top Left corner as anchor point
offset="0.3c/-0.3c", # x / y directions, in centimeters
font="12p",
fill="white@30", # Fill box in white with a transparency of 30 %
perspective=True,
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should skip this part and only focus on draping?

Copy link
Member Author

@yvonnefroehlich yvonnefroehlich Aug 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apologize for the delay with this tutorial 🙁!

I also thought about this. Maybe we can remove this part for now (see commit 5f423b3), to get this tutorial into the release of v0.13.0.

However, I am not 100 % happy with this, as I feel that users actually like to plot more details on top of the 3-D surface. Maybe we can add this later or create a separate tutorial on how to do this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as I feel that users actually like to plot more details on top of the 3-D surface. Maybe we can add this later or create a separate tutorial on how to do this.

Sounds good to me.

Copy link
Member

@seisman seisman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@seisman seisman changed the title WIP: Tutorial: Adding a data set on top of a topographic surface via "drapegrid" of "Figure.grdview" Tutorial: Adding a data set on top of a topographic surface via "drapegrid" of "Figure.grdview" Sep 1, 2024
@seisman seisman added the final review call This PR requires final review and approval from a second reviewer label Sep 1, 2024
@seisman seisman marked this pull request as ready for review September 1, 2024 07:22
@seisman seisman merged commit 0ec4c98 into main Sep 2, 2024
10 checks passed
@seisman seisman deleted the add-gallery-image-on-elevation branch September 2, 2024 11:47
@yvonnefroehlich yvonnefroehlich removed the final review call This PR requires final review and approval from a second reviewer label Sep 7, 2024
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants