diff --git a/examples/tutorials/advanced/cartesian_histograms.py b/examples/tutorials/advanced/cartesian_histograms.py index ad32abfc6e2..5f089227bc5 100644 --- a/examples/tutorials/advanced/cartesian_histograms.py +++ b/examples/tutorials/advanced/cartesian_histograms.py @@ -18,6 +18,7 @@ # Import the required packages import numpy as np import pygmt +from pygmt.params import Pattern # %% # Generate random data from a normal distribution: @@ -204,10 +205,8 @@ frame=["wSnE", "xaf10", "ya5f1+lCumulative counts"], data=data01, series=10, - # Use pattern ("p") number 8 as fill for the bars - # Set the background ("+b") to white [Default] - # Set the foreground ("+f") to black [Default] - fill="p8+bwhite+fblack", + # Fill bars with GMT pattern 8, with white background and black foreground. + fill=Pattern(8, bgcolor="white", fgcolor="black"), pen="1p,darkgray,solid", histtype=0, # Show cumulative counts diff --git a/examples/tutorials/advanced/focal_mechanisms.py b/examples/tutorials/advanced/focal_mechanisms.py index b44286b6397..9c9eaa45145 100644 --- a/examples/tutorials/advanced/focal_mechanisms.py +++ b/examples/tutorials/advanced/focal_mechanisms.py @@ -18,6 +18,7 @@ # %% import pandas as pd import pygmt +from pygmt.params import Pattern # Set up arguments for basemap region = [-5, 5, -5, 5] @@ -122,8 +123,8 @@ longitude=2, latitude=0, depth=0, - compressionfill="p8", - extensionfill="p31", + compressionfill=Pattern(8), + extensionfill=Pattern(31), outline=True, ) diff --git a/pygmt/params/__init__.py b/pygmt/params/__init__.py index f2904afba94..b80b921407a 100644 --- a/pygmt/params/__init__.py +++ b/pygmt/params/__init__.py @@ -3,3 +3,4 @@ """ from pygmt.params.box import Box +from pygmt.params.pattern import Pattern diff --git a/pygmt/params/pattern.py b/pygmt/params/pattern.py new file mode 100644 index 00000000000..ba8f1f8e0c4 --- /dev/null +++ b/pygmt/params/pattern.py @@ -0,0 +1,65 @@ +""" +The Pattern class for specifying GMT filling patterns. +""" + +import dataclasses + +from pygmt.alias import Alias +from pygmt.exceptions import GMTValueError +from pygmt.params.base import BaseParam + + +@dataclasses.dataclass(repr=False) +class Pattern(BaseParam): + """ + + Examples + -------- + >>> from pygmt.params import Pattern + >>> str(Pattern(id=1)) + 'p1' + >>> str(Pattern(id=1, bgcolor="red", fgcolor="blue")) + 'p1+bred+fblue' + >>> str(Pattern(id=1, bgcolor="red", fgcolor="blue", dpi=300)) + 'p1+bred+fblue+r300' + >>> str(Pattern(id="my_pattern.png")) + 'pmy_pattern.png' + >>> str(Pattern(id=2, reversed=True)) + 'P2' + >>> str(Pattern(id=100)) + Traceback (most recent call last): + ... + pygmt.exceptions.GMTValueError: Invalid pattern id: 100... + """ + + id: int | str + reversed: bool = False + bgcolor: str | None = None + fgcolor: str | None = None + dpi: int | None = None + + def __post_init__(self): + """ + Validate the id and set the reversed flag. + """ + if isinstance(self.id, int) and not (1 <= self.id <= 90): + raise GMTValueError( + self.id, + description="pattern id", + reason=( + "Pattern id must be an integer in the range 1-90 " + "or the name of a 1-, 8-, or 24-bit image raster file" + ), + ) + + @property + def _aliases(self): + """ + Aliases for the Pattern class. + """ + return [ + Alias(self.id, name="id", prefix="P" if self.reversed else "p"), + Alias(self.bgcolor, name="bgcolor", prefix="+b"), + Alias(self.fgcolor, name="fgcolor", prefix="+f"), + Alias(self.dpi, name="dpi", prefix="+r"), + ]