Skip to content

Commit b1ad5e0

Browse files
committed
Wrap plot3d
Wrapping the `plot3d` function! Original GMT `plot3d` function can be found at https://docs.generic-mapping-tools.org/latest/plot3d.html. Current implementation is mostly copy-modify-pasted from `plot`, including the tests. Also modified added extra aliases to the `basemap` function to make it 3D capable.
1 parent ee4694e commit b1ad5e0

14 files changed

+453
-7
lines changed

doc/api/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Plotting data and laying out the map:
2626
Figure.coast
2727
Figure.colorbar
2828
Figure.plot
29+
Figure.plot3d
2930
Figure.contour
3031
Figure.grdcontour
3132
Figure.grdimage

pygmt/base_plotting.py

+142-7
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,132 @@ def plot(self, x=None, y=None, data=None, sizes=None, direction=None, **kwargs):
545545
arg_str = " ".join([fname, build_arg_string(kwargs)])
546546
lib.call_module("plot", arg_str)
547547

548+
@fmt_docstring
549+
@use_alias(
550+
R="region",
551+
J="projection",
552+
Jz="zscale",
553+
JZ="zsize",
554+
B="frame",
555+
S="style",
556+
G="color",
557+
W="pen",
558+
i="columns",
559+
l="label",
560+
C="cmap",
561+
p="perspective",
562+
)
563+
@kwargs_to_strings(R="sequence", i="sequence_comma", p="sequence")
564+
def plot3d(
565+
self, x=None, y=None, z=None, data=None, sizes=None, direction=None, **kwargs
566+
):
567+
"""
568+
Plot lines, polygons, and symbols in 3-D
569+
570+
Takes a matrix, (x,y,z) triplets, or a file name as input and plots lines,
571+
polygons, or symbols at those locations in 3-D.
572+
573+
Must provide either *data* or *x*, *y* and *z*.
574+
575+
#If providing data through *x* and *y*, *color* (G) can be a 1d array
576+
#that will be mapped to a colormap.
577+
578+
If a symbol is selected and no symbol size given, then plot3d will
579+
interpret the fourth column of the input data as symbol size. Symbols
580+
whose size is <= 0 are skipped. If no symbols are specified then the
581+
symbol code (see *S* below) must be present as last column in the
582+
input. If *S* is not used, a line connecting the data points will be
583+
drawn instead. To explicitly close polygons, use *L*. Select a fill
584+
with *G*. If *G* is set, *W* will control whether the polygon outline
585+
is drawn or not. If a symbol is selected, *G* and *W* determines the
586+
fill and outline/no outline, respectively.
587+
588+
Full option list at :gmt-docs:`plot3d.html`
589+
590+
{aliases}
591+
592+
Parameters
593+
----------
594+
x/y/z : float or 1d arrays
595+
The x, y, and z coordinates, or arrays of x, y and z coordinates of
596+
the data points
597+
data : str or 2d array
598+
Either a data file name or a 2d numpy array with the tabular data.
599+
Use option *columns* (i) to choose which columns are x, y, z,
600+
color, and size, respectively.
601+
sizes : 1d array
602+
The sizes of the data points in units specified in *style* (S).
603+
Only valid if using *x*, *y* and *z*.
604+
direction : list of two 1d arrays
605+
If plotting vectors (using ``style='V'`` or ``style='v'``), then
606+
should be a list of two 1d arrays with the vector directions. These
607+
can be angle and length, azimuth and length, or x and y components,
608+
depending on the style options chosen.
609+
{J}
610+
zscale/zsize : float or str
611+
Set z-axis scaling or z-axis size.
612+
{R}
613+
A : bool or str
614+
``'[m|p|x|y]'``
615+
By default, geographic line segments are drawn as great circle
616+
arcs. To draw them as straight lines, use *A*.
617+
{B}
618+
{CPT}
619+
D : str
620+
``'dx/dy'``: Offset the plot symbol or line locations by the given
621+
amounts dx/dy.
622+
E : bool or str
623+
``'[x|y|X|Y][+a][+cl|f][+n][+wcap][+ppen]'``.
624+
Draw symmetrical error bars.
625+
{G}
626+
S : str
627+
Plot symbols (including vectors, pie slices, fronts, decorated or
628+
quoted lines).
629+
{W}
630+
{U}
631+
l : str
632+
Add a legend entry for the symbol or line being plotted.
633+
perspective : list or str
634+
``'[x|y|z]azim[/elev[/zlevel]][+wlon0/lat0[/z0]][+vx0/y0]'``.
635+
Select perspective view.
636+
637+
"""
638+
kwargs = self._preprocess(**kwargs)
639+
640+
kind = data_kind(data, x, y, z)
641+
642+
extra_arrays = []
643+
if "S" in kwargs and kwargs["S"][0] in "vV" and direction is not None:
644+
extra_arrays.extend(direction)
645+
if "G" in kwargs and not isinstance(kwargs["G"], str):
646+
if kind != "vectors":
647+
raise GMTInvalidInput(
648+
"Can't use arrays for color if data is matrix or file."
649+
)
650+
extra_arrays.append(kwargs["G"])
651+
del kwargs["G"]
652+
if sizes is not None:
653+
if kind != "vectors":
654+
raise GMTInvalidInput(
655+
"Can't use arrays for sizes if data is matrix or file."
656+
)
657+
extra_arrays.append(sizes)
658+
659+
with Session() as lib:
660+
# Choose how data will be passed in to the module
661+
if kind == "file":
662+
file_context = dummy_context(data)
663+
elif kind == "matrix":
664+
file_context = lib.virtualfile_from_matrix(data)
665+
elif kind == "vectors":
666+
file_context = lib.virtualfile_from_vectors(
667+
np.atleast_1d(x), np.atleast_1d(y), np.atleast_1d(z), *extra_arrays
668+
)
669+
670+
with file_context as fname:
671+
arg_str = " ".join([fname, build_arg_string(kwargs)])
672+
lib.call_module("plot3d", arg_str)
673+
548674
@fmt_docstring
549675
@use_alias(
550676
R="region",
@@ -623,16 +749,18 @@ def contour(self, x=None, y=None, z=None, data=None, **kwargs):
623749
lib.call_module("contour", arg_str)
624750

625751
@fmt_docstring
626-
@use_alias(R="region", J="projection", B="frame")
627-
@kwargs_to_strings(R="sequence")
752+
@use_alias(
753+
R="region", J="projection", Jz="zscale", JZ="zsize", B="frame", p="perspective"
754+
)
755+
@kwargs_to_strings(R="sequence", p="sequence")
628756
def basemap(self, **kwargs):
629757
"""
630-
Produce a basemap for the figure.
758+
Plot base maps and frames for the figure.
631759
632-
Several map projections are available, and the user may specify
633-
separate tick-mark intervals for boundary annotation, ticking, and
634-
[optionally] gridlines. A simple map scale or directional rose may also
635-
be plotted.
760+
Creates a basic or fancy basemap with axes, fill, and titles. Several
761+
map projections are available, and the user may specify separate
762+
tick-mark intervals for boundary annotation, ticking, and [optionally]
763+
gridlines. A simple map scale or directional rose may also be plotted.
636764
637765
At least one of the options *B*, *L*, or *T* must be specified.
638766
@@ -656,6 +784,13 @@ def basemap(self, **kwargs):
656784
reference and anchor points
657785
{U}
658786
787+
zscale/zsize : float or str
788+
Set z-axis scaling or z-axis size.
789+
790+
perspective : list or str
791+
``'[x|y|z]azim[/elev[/zlevel]][+wlon0/lat0[/z0]][+vx0/y0]'``.
792+
Select perspective view.
793+
659794
"""
660795
kwargs = self._preprocess(**kwargs)
661796
if not ("B" in kwargs or "L" in kwargs or "T" in kwargs):
34.2 KB
Loading
Loading
Loading
75.9 KB
Loading
53.5 KB
Loading
Loading
27.7 KB
Loading
34.2 KB
Loading
35.9 KB
Loading
28.5 KB
Loading
27.7 KB
Loading

0 commit comments

Comments
 (0)