From eedd76a99888adbd5334e9353b5139f51add3f6a Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Sat, 24 Apr 2021 22:54:09 +1200 Subject: [PATCH 1/4] Initialize pygmt.param.Pen class for specifying pen attributes Start a `pygmt.param.Pen` convenience class that generates a string which can be passed into GMT's pen (-W) parameter. The Pen class is structured to be under a 'param' folder. Added three basic unit tests to ensure various width/color/style combinations will be output correctly. --- pygmt/__init__.py | 2 +- pygmt/param/__init__.py | 4 ++++ pygmt/param/pen.py | 22 ++++++++++++++++++++++ pygmt/tests/test_params_pen.py | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 pygmt/param/__init__.py create mode 100644 pygmt/param/pen.py create mode 100644 pygmt/tests/test_params_pen.py diff --git a/pygmt/__init__.py b/pygmt/__init__.py index 1dc2ed79ac4..3d68893c01b 100644 --- a/pygmt/__init__.py +++ b/pygmt/__init__.py @@ -23,7 +23,7 @@ from pkg_resources import get_distribution # Import modules to make the high-level GMT Python API -from pygmt import datasets +from pygmt import datasets, param from pygmt.accessors import GMTDataArrayAccessor from pygmt.figure import Figure, set_display from pygmt.session_management import begin as _begin diff --git a/pygmt/param/__init__.py b/pygmt/param/__init__.py new file mode 100644 index 00000000000..d6892082224 --- /dev/null +++ b/pygmt/param/__init__.py @@ -0,0 +1,4 @@ +""" +PyGMT convenience parameter classes. +""" +from pygmt.param.pen import Pen diff --git a/pygmt/param/pen.py b/pygmt/param/pen.py new file mode 100644 index 00000000000..24e4314af75 --- /dev/null +++ b/pygmt/param/pen.py @@ -0,0 +1,22 @@ +""" +Define the Pen class for specifying pen attributes (width, color, style). +""" +from dataclasses import dataclass + + +@dataclass +class Pen: + """ + A GMT pen specified from three attributes: *width*, *color* and *style*. + + See also :gmt-docs:`cookbook/features.html#specifying-pen-attributes` + """ + + width: str = None + color: str = None + style: str = None + + def __str__(self): + return ",".join( + str(attr or "") for attr in (self.width, self.color, self.style) + ) diff --git a/pygmt/tests/test_params_pen.py b/pygmt/tests/test_params_pen.py new file mode 100644 index 00000000000..9170f461d2f --- /dev/null +++ b/pygmt/tests/test_params_pen.py @@ -0,0 +1,32 @@ +""" +Tests for the Pen param class. +""" +from pygmt.param import Pen + + +def test_param_pen_width_or_color_or_style_only(): + """ + Test that Pen returns correctly formatted pen syntax when only one + attribute (width or color or style) is given. + """ + assert str(Pen(width=1)) == "1,," + assert str(Pen(color="yellow")) == ",yellow," + assert str(Pen(style="-.-")) == ",,-.-" + + +def test_param_pen_two_attributes(): + """ + Test that Pen returns correctly formatted pen syntax when two attributes + (width/color or width/style or color/style) are given. + """ + assert str(Pen(width=0.2, color="blue")) == "0.2,blue," + assert str(Pen(style="-.-", width="faint")) == "faint,,-.-" + assert str(Pen(color="255/128/0", style="4_8_5_8:2p")) == ",255/128/0,4_8_5_8:2p" + + +def test_param_pen_three_attributes(): + """ + Test that Pen returns correctly formatted pen syntax when three attributes + (width and color and style) are given. + """ + assert str(Pen(style=".-.-", color="120-1-1", width="0.5c")) == "0.5c,120-1-1,.-.-" From 5ecea7793cd49a7d550b0c18a2810407e5a59988 Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Sat, 24 Apr 2021 23:50:01 +1200 Subject: [PATCH 2/4] Add param.Pen to doc/api/index.rst and add extra docstrings Placing the API docs for param.Pen under a new 'Parameters' subsection. 'Specifying pen attributes' documentation is copied from GMT cookbook, with examples modified to use the PyGMT syntax. --- doc/api/index.rst | 10 +++++ pygmt/param/pen.py | 94 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/doc/api/index.rst b/doc/api/index.rst index 7d30a2a0d75..c97bdca6def 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -120,6 +120,16 @@ Getting metadata from tabular or grid data: info grdinfo +Parameters +---------- + +Complex GMT arguments can be specified using convenience classes under +the :mod:`pygmt.param` module. + +.. autosummary:: + :toctree: generated + + param.Pen Miscellaneous ------------- diff --git a/pygmt/param/pen.py b/pygmt/param/pen.py index 24e4314af75..2c3ea14200e 100644 --- a/pygmt/param/pen.py +++ b/pygmt/param/pen.py @@ -10,6 +10,100 @@ class Pen: A GMT pen specified from three attributes: *width*, *color* and *style*. See also :gmt-docs:`cookbook/features.html#specifying-pen-attributes` + + Attributes + ---------- + width : str or int + [*width*\ [**c**\|\ **i**\|\ **p**]]. + *Width* is by default measured in points (1/72 of an inch). Append + **c**, **i**, or **p** to specify pen width in cm, inch, or points, + respectively. Minimum-thickness pens can be achieved by giving zero + width. The result is device-dependent but typically means that as you + zoom in on the feature in a display, the line thickness stays at the + minimum. Finally, a few predefined pen names can be used: default, + faint, and {thin, thick, fat}[er\|\ est], and wide. + + +------------+---------+------------+--------+ + +============+=========+============+========+ + | faint | 0 | thicker | 1.5p | + +------------+---------+------------+--------+ + | default | 0.25p | thickest | 2p | + +------------+---------+------------+--------+ + | thinnest | 0.25p | fat | 3p | + +------------+---------+------------+--------+ + | thinner | 0.50p | fatter | 6p | + +------------+---------+------------+--------+ + | thin | 0.75p | fattest | 10p | + +------------+---------+------------+--------+ + | thick | 1.0p | wide | 18p | + +------------+---------+------------+--------+ + + color : str + The *color* can be specified in five different ways: + + - Gray. Specify a *gray* shade in the range 0–255 (linearly going + from black [0] to white [255]). + + - RGB. Specify *r*/*g*/*b*, each ranging from 0–255. Here 0/0/0 is + black, 255/255/255 is white, 255/0/0 is red, etc. Alternatively, + you can give RGB in hexadecimal using the *#rrggbb* format. + + - HSV. Specify *hue*-*saturation*-*value*, with the former in the + 0–360 degree range while the latter two take on the range 0–1 [17]_. + + - CMYK. Specify *cyan*/*magenta*/*yellow*/*black*, each ranging + from 0–100%. + + - Name. Specify one of 663 valid color names. See + :gmt-docs:`gmtcolors` for a list of all valid names. A very small + yet versatile subset consists of the 29 choices *white*, *black*, and + [light\|\ dark]{*red, orange, yellow, green, cyan, blue, magenta, + gray\|\ grey, brown*\ }. The color names are case-insensitive, so + mixed upper and lower case can be used (like *DarkGreen*). + + style : str + [*style*\ [**c**\|\ **i**\|\ **p**]]. + The *style* attribute controls the appearance of the line. Giving + "dotted" or "." yields a dotted line, whereas a dashed pen is requested + with "dashed" or "-". Also combinations of dots and dashes, like ".-" + for a dot-dashed line, are allowed. To override a default style and + secure a solid line you can specify "solid" for style. The lengths of + dots and dashes are scaled relative to the pen width (dots has a length + that equals the pen width while dashes are 8 times as long; gaps + between segments are 4 times the pen width). For more detailed + attributes including exact dimensions you may specify + *string*\ [:*offset*], where *string* is a series of numbers separated + by underscores. These numbers represent a pattern by indicating the + length of line segments and the gap between segments. The optional + *offset* phase-shifts the pattern from the beginning the line [0]. For + example, if you want a yellow line of width 0.1 cm that alternates + between long dashes (4 points), an 8 point gap, then a 5 point dash, + then another 8 point gap, with pattern offset by 2 points from the + origin, specify ``style="0.1c,yellow,4_8_5_8:2p"``. Just as with pen + width, the default style units are points, but can also be explicitly + specified in cm, inch, or points (see *width* discussion above). + + Examples + -------- + >>> import pygmt + + >>> # 0.5 point wide line of default color and style + >>> pen = pygmt.param.Pen(width="0.5p") + + >>> # Green line with default width and style + >>> pen = pygmt.param.Pen(color="green") + + >>> # Dashed, thin red line + >>> pen = pygmt.param.Pen(width="thin", color="red", style="-") + + >>> # Fat dotted line with default color + >>> pen = pygmt.param.Pen(width="fat", style=".") + + >>> # Green (in h-s-v) pen, 1 mm thick + >>> pen = pygmt.param.Pen(width="0.1c", color="120-1-1") + + >>> # Very thin, cyan (in c/m/y/k), dot-dot-dashed line + >>> pen = pygmt.param.Pen(width="faint", color="100/0/0/0", style="..-") """ width: str = None From 995465858584ca9d496381fdace67adecca78fac Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Sun, 25 Apr 2021 00:08:19 +1200 Subject: [PATCH 3/4] Add doctest example for a thick, purple, dash-dot-dash pen --- pygmt/param/pen.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pygmt/param/pen.py b/pygmt/param/pen.py index 2c3ea14200e..606a6988b7f 100644 --- a/pygmt/param/pen.py +++ b/pygmt/param/pen.py @@ -104,6 +104,14 @@ class Pen: >>> # Very thin, cyan (in c/m/y/k), dot-dot-dashed line >>> pen = pygmt.param.Pen(width="faint", color="100/0/0/0", style="..-") + + >>> # Thick, purple, dashed-dot-dashed border line around some text + >>> pen = pygmt.param.Pen(width="thick", color="purple", style="-.-") + >>> print(pen) + thick,purple,-.- + >>> fig = pygmt.Figure() + >>> fig.text(x=1, y=1, region=[0, 2, 0, 2], pen=pen, text=pen) + >>> fig.show() """ width: str = None From 86a2df9596e5578eb2e2dda847df1374c41d8c7b Mon Sep 17 00:00:00 2001 From: Wei Ji <23487320+weiji14@users.noreply.github.com> Date: Sun, 25 Apr 2021 00:31:29 +1200 Subject: [PATCH 4/4] [skip-ci] Use raw-string for param.Pen's docstring --- pygmt/param/pen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/param/pen.py b/pygmt/param/pen.py index 606a6988b7f..e47cdd564aa 100644 --- a/pygmt/param/pen.py +++ b/pygmt/param/pen.py @@ -6,7 +6,7 @@ @dataclass class Pen: - """ + r""" A GMT pen specified from three attributes: *width*, *color* and *style*. See also :gmt-docs:`cookbook/features.html#specifying-pen-attributes`