GenericMappingTools / pygmt

A Python interface for the Generic Mapping Tools.
https://www.pygmt.org
BSD 3-Clause "New" or "Revised" License
758 stars 220 forks source link

Let PyGMT accept a 1d array when 2d array is needed #1132

Open seisman opened 3 years ago

seisman commented 3 years ago

The issue was first found in https://github.com/GenericMappingTools/pygmt/pull/1070#discussion_r602617399.

Below is a simple example plotting a circular vector. The data parameter expects a 2D array/list. Each row is a record, and the 5 columns are [x_start, y_start, radius, degree_start, degree_stop].

The following script works as expected because the variable data is a 2D array/list:

import numpy as np
import pygmt

fig = pygmt.Figure()
fig.plot(
    region=[-10, 10, -10, 10],
    projection="X10c",
    frame="ag",
    data=[[0, 0, 2.5, 90, 270], [0, 0, 1.5, 90, 270]],
    style="m0.5c+ea",
    pen="2p",
    color="red3",
)
fig.show()

When users want to plot a single circular vector, they still have to pass a 2D list, so the code looks like:

data=[[0, 0, 2.5, 90, 270]]

However, most people may first try a 1D array and then realize it doesn't work as expected.

data=[0, 0, 2.5, 90, 270]

As I understand it, data always expects a 2D array/list. When a 1D array is given, can we convert it to a 2D array? Are there any negative effects?

seisman commented 3 years ago

Similarly, parameters like x and y usually expect a 1D array/list, but PyGMT allow passing scalar values to them.

noorbuchi commented 3 years ago

Hello! I tried the example you mentioned in the issue description and I got this error message.

'list' object has no attribute 'flags'

So it looks like even passing a 2D array would cause an error. To solve it, I had to pass the 2D array into a numpy array object to see the plot. I don't know if it's important to know but I ran the code using Jupyter Notebook.

fig = pygmt.Figure()
fig.plot(
    region=[-10, 10, -10, 10],
    projection="X10c",
    frame="ag",
    data=numpy.array([[0, 0, 2.5, 90, 270], [0, 0, 1.5, 90, 270]]),
    style="m0.5c+ea",
    pen="2p",
    color="red3",
)
fig.show()
seisman commented 3 years ago

It works for me. What's your PyGMT and GMT versions?

python -c "import pygmt; pygmt.show_versions()"
noorbuchi commented 3 years ago

This is what I got:

PyGMT information:
  version: v0.3.0
System information:
  python: 3.8.5 (default, Sep  4 2020, 07:30:14)  [GCC 7.3.0]
  executable: /home/buchin/miniconda3/bin/python
  machine: Linux-5.4.0-70-generic-x86_64-with-glibc2.10
Dependency information:
  numpy: 1.20.1
  pandas: 1.2.3
  xarray: 0.17.0
  netCDF4: 1.5.6
  packaging: 20.9
  ghostscript: 9.53.3
  gmt: 6.1.1
GMT library information:
  binary dir: /home/buchin/miniconda3/bin
  cores: 4
  grid layout: rows
  library path: /home/buchin/miniconda3/lib/libgmt.so
  padding: 2
  plugin dir: /home/buchin/miniconda3/lib/gmt/plugins
  share dir: /home/buchin/miniconda3/share/gmt
  version: 6.1.1
seisman commented 3 years ago

You're using PyGMT v0.3.0, but the latest one is v0.3.1. I think the 'list' object has no attribute 'flags' error was fixed in #990.

noorbuchi commented 3 years ago

That makes a lot of sense! I haven't been keeping up with the latest updates. I'll try updating and see if it fixes the issue. I'll keep you posted

noorbuchi commented 3 years ago

I just updated to v0.3.1. and your example is working! It still doesn't accept 1D array as you already mentioned