Skip to content

Commit 42e2b28

Browse files
committed
Merge branch 'master' into grdimage/document_all_args
2 parents d2b6997 + faf197e commit 42e2b28

File tree

5 files changed

+125
-11
lines changed

5 files changed

+125
-11
lines changed

pygmt/base_plotting.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ def _preprocess(self, **kwargs): # pylint: disable=no-self-use
6868
G="land",
6969
S="water",
7070
U="timestamp",
71+
X="xshift",
72+
Y="yshift",
7173
t="transparency",
7274
)
7375
@kwargs_to_strings(R="sequence")
@@ -129,6 +131,7 @@ def coast(self, **kwargs):
129131
shorelines : str
130132
``'[level/]pen'``
131133
Draw shorelines [Default is no shorelines]. Append pen attributes.
134+
{XY}
132135
{t}
133136
134137
"""
@@ -146,6 +149,8 @@ def coast(self, **kwargs):
146149
F="box",
147150
G="truncate",
148151
W="scale",
152+
X="xshift",
153+
Y="yshift",
149154
t="transparency",
150155
)
151156
@kwargs_to_strings(R="sequence", G="sequence")
@@ -208,6 +213,7 @@ def colorbar(self, **kwargs):
208213
scale : float
209214
Multiply all z-values in the CPT by the provided scale. By default
210215
the CPT is used as is.
216+
{XY}
211217
{t}
212218
213219
"""
@@ -229,6 +235,8 @@ def colorbar(self, **kwargs):
229235
U="timestamp",
230236
W="pen",
231237
l="label",
238+
X="xshift",
239+
Y="yshift",
232240
t="transparency",
233241
)
234242
@kwargs_to_strings(R="sequence", L="sequence", A="sequence_plus")
@@ -279,6 +287,7 @@ def grdcontour(self, grid, **kwargs):
279287
{G}
280288
{U}
281289
{W}
290+
{XY}
282291
label : str
283292
Add a legend entry for the contour being plotted. Normally, the
284293
annotated contour is selected for the legend. You can select the
@@ -317,8 +326,11 @@ def grdcontour(self, grid, **kwargs):
317326
R="region",
318327
U="timestamp",
319328
V="verbose",
329+
X="xshift",
330+
Y="yshift",
320331
n="interpolation",
321332
t="transparency",
333+
x="cores",
322334
)
323335
@kwargs_to_strings(R="sequence")
324336
def grdimage(self, grid, **kwargs):
@@ -422,8 +434,10 @@ def grdimage(self, grid, **kwargs):
422434
3).
423435
{R}
424436
{V}
437+
{XY}
425438
{n}
426439
{t}
440+
{x}
427441
428442
"""
429443
kwargs = self._preprocess(**kwargs)
@@ -455,6 +469,8 @@ def grdimage(self, grid, **kwargs):
455469
Wf="facadepen",
456470
p="perspective",
457471
I="shading",
472+
X="xshift",
473+
Y="yshift",
458474
t="transparency",
459475
)
460476
@kwargs_to_strings(R="sequence", p="sequence")
@@ -532,6 +548,7 @@ def grdview(self, grid, **kwargs):
532548
intensity, and ambient arguments for that module, or just give
533549
``+d`` to select the default arguments (``+a-45+nt1+m0``).
534550
551+
{XY}
535552
{t}
536553
537554
"""
@@ -573,6 +590,8 @@ def grdview(self, grid, **kwargs):
573590
l="label",
574591
C="cmap",
575592
U="timestamp",
593+
X="xshift",
594+
Y="yshift",
576595
t="transparency",
577596
)
578597
@kwargs_to_strings(R="sequence", i="sequence_comma")
@@ -641,6 +660,7 @@ def plot(self, x=None, y=None, data=None, sizes=None, direction=None, **kwargs):
641660
quoted lines).
642661
{W}
643662
{U}
663+
{XY}
644664
label : str
645665
Add a legend entry for the symbol or line being plotted.
646666
@@ -694,6 +714,8 @@ def plot(self, x=None, y=None, data=None, sizes=None, direction=None, **kwargs):
694714
i="columns",
695715
l="label",
696716
C="levels",
717+
X="xshift",
718+
Y="yshift",
697719
t="transparency",
698720
)
699721
@kwargs_to_strings(R="sequence", i="sequence_comma")
@@ -752,6 +774,7 @@ def contour(self, x=None, y=None, z=None, data=None, **kwargs):
752774
to be of the format [*annotcontlabel*][/*contlabel*]. If either
753775
label contains a slash (/) character then use ``|`` as the
754776
separator for the two labels instead.
777+
{XY}
755778
{t}
756779
757780
"""
@@ -783,6 +806,8 @@ def contour(self, x=None, y=None, z=None, data=None, **kwargs):
783806
Td="rose",
784807
Tm="compass",
785808
U="timestamp",
809+
X="xshift",
810+
Y="yshift",
786811
t="transparency",
787812
)
788813
@kwargs_to_strings(R="sequence")
@@ -817,6 +842,7 @@ def basemap(self, **kwargs):
817842
Draws a map magnetic rose on the map at the location defined by the
818843
reference and anchor points
819844
{U}
845+
{XY}
820846
{t}
821847
822848
"""
@@ -833,6 +859,8 @@ def basemap(self, **kwargs):
833859
U="timestamp",
834860
D="position",
835861
F="box",
862+
X="xshift",
863+
Y="yshift",
836864
t="transparency",
837865
)
838866
@kwargs_to_strings(R="sequence")
@@ -860,6 +888,7 @@ def logo(self, **kwargs):
860888
Without further options, draws a rectangular border around the
861889
GMT logo.
862890
{U}
891+
{XY}
863892
{t}
864893
865894
"""
@@ -876,6 +905,8 @@ def logo(self, **kwargs):
876905
D="position",
877906
F="box",
878907
M="monochrome",
908+
X="xshift",
909+
Y="yshift",
879910
t="transparency",
880911
)
881912
@kwargs_to_strings(R="sequence")
@@ -911,6 +942,7 @@ def image(self, imagefile, **kwargs):
911942
monochrome : bool
912943
Convert color image to monochrome grayshades using the (television)
913944
YIQ-transformation.
945+
{XY}
914946
{t}
915947
"""
916948
kwargs = self._preprocess(**kwargs)
@@ -924,6 +956,8 @@ def image(self, imagefile, **kwargs):
924956
J="projection",
925957
D="position",
926958
F="box",
959+
X="xshift",
960+
Y="yshift",
927961
t="transparency",
928962
)
929963
@kwargs_to_strings(R="sequence")
@@ -960,6 +994,7 @@ def legend(self, spec=None, position="JTR+jTR+o0.2c", box="+gwhite+p1p", **kwarg
960994
rectangular border around the legend using **MAP_FRAME_PEN**. By
961995
default, uses '+gwhite+p1p' which draws a box around the legend
962996
using a 1 point black pen and adds a white background.
997+
{XY}
963998
{t}
964999
"""
9651000
kwargs = self._preprocess(**kwargs)
@@ -989,6 +1024,8 @@ def legend(self, spec=None, position="JTR+jTR+o0.2c", box="+gwhite+p1p", **kwarg
9891024
D="offset",
9901025
G="fill",
9911026
W="pen",
1027+
X="xshift",
1028+
Y="yshift",
9921029
t="transparency",
9931030
)
9941031
@kwargs_to_strings(
@@ -1095,6 +1132,7 @@ def text(
10951132
Sets the pen used to draw a rectangle around the text string
10961133
(see *clearance*) [Default is width = default, color = black,
10971134
style = solid].
1135+
{XY}
10981136
{t}
10991137
"""
11001138
kwargs = self._preprocess(**kwargs)
@@ -1150,6 +1188,8 @@ def text(
11501188
J="projection",
11511189
B="frame",
11521190
C="offset",
1191+
X="xshift",
1192+
Y="yshift",
11531193
t="transparency",
11541194
)
11551195
@kwargs_to_strings(R="sequence")
@@ -1247,6 +1287,7 @@ def meca(
12471287
{J}
12481288
{R}
12491289
{B}
1290+
{XY}
12501291
{t}
12511292
"""
12521293

pygmt/helpers/decorators.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@
5353
"W": """\
5454
pen : str
5555
Set pen attributes for lines or the outline of symbols.""",
56+
"XY": """\
57+
xshift : str
58+
``[a|c|f|r][xshift]``.
59+
Shift plot origin in x-direction.
60+
yshift : str
61+
``[a|c|f|r][yshift]``.
62+
Shift plot origin in y-direction. Full documentation is at
63+
:gmt-docs:`gmt.html#xy-full`.
64+
""",
5665
"j": """\
5766
distcalc : str
5867
``e|f|g``.
@@ -89,6 +98,16 @@
8998
Only visible when PDF or raster format output is selected.
9099
Only the PNG format selection adds a transparency layer
91100
in the image (for further processing). """,
101+
"x": """\
102+
cores : int
103+
``[[-]n]``.
104+
Limit the number of cores to be used in any OpenMP-enabled
105+
multi-threaded algorithms. By default we try to use all available
106+
cores. Set a number *n* to only use n cores (if too large it will
107+
be truncated to the maximum cores available). Finally, give a
108+
negative number *-n* to select (all - n) cores (or at least 1 if
109+
n equals or exceeds all).
110+
""",
92111
}
93112

94113

pygmt/helpers/utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ def is_nonstr_iter(value):
172172
True
173173
>>> is_nonstr_iter((1, 2, 3))
174174
True
175+
>>> import numpy as np
176+
>>> is_nonstr_iter(np.array([1.0, 2.0, 3.0]))
177+
True
178+
>>> is_nonstr_iter(np.array(["abc", "def", "ghi"]))
179+
True
175180
176181
"""
177182
return isinstance(value, Iterable) and not isinstance(value, str)

pygmt/modules.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,10 @@ def info(table, **kwargs):
7878
7979
Parameters
8080
----------
81-
table : pandas.DataFrame or np.ndarray or str
82-
Either a pandas dataframe, a 1D/2D numpy.ndarray or a file name to an
83-
ASCII data table.
81+
table : str or np.ndarray or pandas.DataFrame or xarray.Dataset
82+
Pass in either a file name to an ASCII data table, a 1D/2D numpy array,
83+
a pandas dataframe, or an xarray dataset made up of 1D xarray.DataArray
84+
data variables.
8485
per_column : bool
8586
Report the min/max values per column in separate columns.
8687
spacing : str
@@ -107,10 +108,13 @@ def info(table, **kwargs):
107108
if kind == "file":
108109
file_context = dummy_context(table)
109110
elif kind == "matrix":
110-
_table = np.asanyarray(table)
111-
if table.ndim == 1: # 1D arrays need to be 2D and transposed
112-
_table = np.transpose(np.atleast_2d(_table))
113-
file_context = lib.virtualfile_from_matrix(_table)
111+
try:
112+
# pandas.DataFrame and xarray.Dataset types
113+
arrays = [array for _, array in table.items()]
114+
except AttributeError:
115+
# Python lists, tuples, and numpy ndarray types
116+
arrays = np.atleast_2d(np.asanyarray(table).T)
117+
file_context = lib.virtualfile_from_vectors(*arrays)
114118
else:
115119
raise GMTInvalidInput(f"Unrecognized data type: {type(table)}")
116120

pygmt/tests/test_info.py

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@
88
import pandas as pd
99
import pytest
1010
import xarray as xr
11+
from packaging.version import Version
1112

12-
from .. import info
13+
from .. import clib, info
1314
from ..exceptions import GMTInvalidInput
1415

1516
TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
1617
POINTS_DATA = os.path.join(TEST_DATA_DIR, "points.txt")
1718

19+
with clib.Session() as _lib:
20+
gmt_version = Version(_lib.info["version"])
21+
1822

1923
def test_info():
2024
"Make sure info works on file name inputs"
@@ -33,7 +37,48 @@ def test_info_dataframe():
3337
table = pd.read_csv(POINTS_DATA, sep=" ", header=None)
3438
output = info(table=table)
3539
expected_output = (
36-
"<matrix memory>: N = 20 <11.5309/61.7074> <-2.9289/7.8648> <0.1412/0.9338>\n"
40+
"<vector memory>: N = 20 <11.5309/61.7074> <-2.9289/7.8648> <0.1412/0.9338>\n"
41+
)
42+
assert output == expected_output
43+
44+
45+
@pytest.mark.xfail(
46+
condition=gmt_version <= Version("6.1.1"),
47+
reason="UNIX timestamps returned instead of ISO datetime, should work on GMT 6.2.0 "
48+
"after https://github.com/GenericMappingTools/gmt/issues/4241 is resolved",
49+
)
50+
def test_info_pandas_dataframe_time_column():
51+
"Make sure info works on pandas.DataFrame inputs with a time column"
52+
table = pd.DataFrame(
53+
data={
54+
"z": [10, 13, 12, 15, 14],
55+
"time": pd.date_range(start="2020-01-01", periods=5),
56+
}
57+
)
58+
output = info(table=table)
59+
expected_output = (
60+
"<vector memory>: N = 5 <10/15> <2020-01-01T00:00:00/2020-01-05T00:00:00>\n"
61+
)
62+
assert output == expected_output
63+
64+
65+
@pytest.mark.xfail(
66+
condition=gmt_version <= Version("6.1.1"),
67+
reason="UNIX timestamp returned instead of ISO datetime, should work on GMT 6.2.0 "
68+
"after https://github.com/GenericMappingTools/gmt/issues/4241 is resolved",
69+
)
70+
def test_info_xarray_dataset_time_column():
71+
"Make sure info works on xarray.Dataset 1D inputs with a time column"
72+
table = xr.Dataset(
73+
coords={"index": [0, 1, 2, 3, 4]},
74+
data_vars={
75+
"z": ("index", [10, 13, 12, 15, 14]),
76+
"time": ("index", pd.date_range(start="2020-01-01", periods=5)),
77+
},
78+
)
79+
output = info(table=table)
80+
expected_output = (
81+
"<vector memory>: N = 5 <10/15> <2020-01-01T00:00:00/2020-01-05T00:00:00>\n"
3782
)
3883
assert output == expected_output
3984

@@ -43,15 +88,15 @@ def test_info_2d_array():
4388
table = np.loadtxt(POINTS_DATA)
4489
output = info(table=table)
4590
expected_output = (
46-
"<matrix memory>: N = 20 <11.5309/61.7074> <-2.9289/7.8648> <0.1412/0.9338>\n"
91+
"<vector memory>: N = 20 <11.5309/61.7074> <-2.9289/7.8648> <0.1412/0.9338>\n"
4792
)
4893
assert output == expected_output
4994

5095

5196
def test_info_1d_array():
5297
"Make sure info works on 1D numpy.ndarray inputs"
5398
output = info(table=np.arange(20))
54-
expected_output = "<matrix memory>: N = 20 <0/19>\n"
99+
expected_output = "<vector memory>: N = 20 <0/19>\n"
55100
assert output == expected_output
56101

57102

0 commit comments

Comments
 (0)