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

plot 2d ndarrays with grdimage #2846

Open
yohaimagen opened this issue Dec 3, 2023 · 6 comments
Open

plot 2d ndarrays with grdimage #2846

yohaimagen opened this issue Dec 3, 2023 · 6 comments
Labels
feature request New feature wanted

Comments

@yohaimagen
Copy link
Contributor

Description of the desired feature

I find myself working with 2D numpy ndarrays often. Then, for visualization purposes, I need to input the data into an xarray DataArray and plot it using pyGMT. I think it would be very convenient if the grdimage function could accept 2D ndarrays along with x and y coordinates. Another option, if PyGMT's grdimage should not change significantly from GMT's grdimage, would be to provide a higher-level function on top of grdimage that does the same. Something that resembles matplotlib's pcolormesh.

Are you willing to help implement and maintain this feature?

Yes

@yohaimagen yohaimagen added the feature request New feature wanted label Dec 3, 2023
@seisman
Copy link
Member

seisman commented Dec 3, 2023

I find myself working with 2D numpy ndarrays often. Then, for visualization purposes, I need to input the data into an xarray DataArray and plot it using pyGMT.

Just want to make sure we're on the same page. Are you writing codes like this?

import numpy as np
import xarray as xr
import pygmt

array = np.arange(200).reshape((10, 20))
data = xr.DataArray(array)
fig = pygmt.Figure()
fig.grdimage(data, frame=True)
fig.show()

@yohaimagen
Copy link
Contributor Author

Not exactly

A simple example is a calculation for parameters x and y, which can represent longitudes and latitudes, but they can also represent anything else.

import numpy as np
import xarray as xr
import pygmt

x = np.linspace(-118, -117,  100) # longitudes
y = np.linspace(35, 36, 100) # latitudes
X, Y = np.meshgrid(x, y)
array = np.zeros_like(X)
for i in range(X.shape[0]):
    for j in range(X.shape[1]):
        array[i, j] = f(X[i, j], Y[i, j])# f calculate something based on x and y
data_array = xr.DataArray(array, coords={'x': x, 'y': y}, dims=('y', 'x'))

fig = pygmt.Figure()
fig.grdimage(data_array, frame=True, projection='M10')
fig.show()
        

@yohaimagen
Copy link
Contributor Author

I think the main point is that it will be nice to be able to plot 2D data without the need to go through raster-like data, whether it be writing it to a raster file or using xarray.

@seisman
Copy link
Member

seisman commented Dec 3, 2023

Not exactly

A simple example is a calculation for parameters x and y, which can represent longitudes and latitudes, but they can also represent anything else.

import numpy as np
import xarray as xr
import pygmt

x = np.linspace(-118, -117,  100) # longitudes
y = np.linspace(35, 36, 100) # latitudes
X, Y = np.meshgrid(x, y)
array = np.zeros_like(X)
for i in range(X.shape[0]):
    for j in range(X.shape[1]):
        array[i, j] = f(X[i, j], Y[i, j])# f calculate something based on x and y
data_array = xr.DataArray(array, coords={'x': x, 'y': y}, dims=('y', 'x'))

fig = pygmt.Figure()
fig.grdimage(data_array, frame=True, projection='M10')
fig.show()
        

We have a similar but simpler example (https://www.pygmt.org/dev/gallery/3d_plots/grdview_surface.html), so your script can be simplified to:

x = np.linspace(-118, -117,  100) # longitudes
y = np.linspace(35, 36, 100) # latitudes
data = xr.DataArray(f(*np.meshgrid(x, y)), coords={'x': x, 'y': y}, dims=('y', 'x'))

@seisman
Copy link
Member

seisman commented Oct 6, 2024

I think we have three options here:

  1. Do nothing and close the issue
  2. Make all grid-related functions (e.g., grdimage/`grdcut``) to accept a 2-D numpy array as input. Internally, we need to (1) check if the input data is a 2-D numpy array; (2) Create a xarray.DataArray object from the 2-D numpy array, with the x/y coords determined from the array shape
  3. Provide a function like matrix2grid to convert a 2-D matrix to a xarray.DataArray object. The function's definition can be something like:
matrix2grid(data, x=None, y=None, region=None, spacing=None)

For reference, GMT.jl also provides a function named mat2grid at https://www.generic-mapping-tools.org/GMTjl_doc/documentation/utilities/mat2grid/index.html.

I'm inclined to option 1 or 3.

@seisman
Copy link
Member

seisman commented Nov 30, 2024

Actually, there is option 4, i.e., let pygmt.xyz2grd support more flexible inputs, as proposed in #2852. More specifically, we should support:

xyz2grd(z=z) # z is a 2-D array.
xyz2grd(x=x, y=y, z=z) # x/y are 1-D arrays and z is a 2-D array.

I think we should implement #2852.

@GenericMappingTools/pygmt-maintainers If no objections, I'll close this feature request. Anyone interested in this feature should track progress in #2852 instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature wanted
Projects
None yet
Development

No branches or pull requests

2 participants