-
Notifications
You must be signed in to change notification settings - Fork 230
Add the Box class for specifying the box of GMT embellishments #3995
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+311
−18
Merged
Changes from all commits
Commits
Show all changes
48 commits
Select commit
Hold shift + click to select a range
b73a6e2
Add the Box class for specifying box properties of embellishments
seisman 9f08d1b
Apply suggestions from code review
seisman 01b563c
Use Box in examples and tests
seisman d2ae10c
Use Box in examples and tests
seisman ec1af1d
Fix API doc
seisman 48702b5
Clarify that subclass must implement the _aliases property
seisman 210292f
Add validate method
seisman 8e5321e
Fix the check logic
seisman 926a690
Change to _validate
seisman b1c6330
Merge branch 'main' into AliasSystem/params/base
seisman bc31c7c
Remove unneeded comments
seisman de1545f
Rename separator to sep
seisman 44b0be3
Merge branch 'main' into AliasSystem/params/base
seisman 1d14eb5
Merge branch 'main' into AliasSystem/params/base
seisman 6ddcf4e
Merge branch 'main' into AliasSystem/params/base
seisman 84ca37e
Merge branch 'main' into AliasSystem/params/base
seisman 0313330
Renanem the section header in doc api page
seisman 40a47a8
Do not display False by default
seisman 457abed
Fix repr
seisman 16c3d6c
Merge branch 'main' into AliasSystem/params/base
seisman ab7ad67
Apply suggestions from code review
seisman 3c1ee05
Merge branch 'main' into AliasSystem/params/base
seisman 9d60637
Merge branch 'main' into AliasSystem/params/base
seisman c4a19a5
Apply suggestions from code review
seisman 5ec1180
Check that inner_pen is set when inner_gap is set
seisman 86d0a32
Fix the check of shading_offset and add a test
seisman 4e98acf
Add more tests
seisman 22fb1eb
Remove print statements
seisman a83f21d
Merge branch 'main' into AliasSystem/params/base
seisman dce0e47
Validate inner_pen/inner_gap in the _validate method
seisman 078dffb
Merge branch 'main' into AliasSystem/params/base
seisman 9b6ae97
Merge branch 'main' into AliasSystem/params/base
seisman e5ef5cf
Add more tests
seisman 8250eb2
Add a real example
seisman 81b2f4f
Merge remote-tracking branch 'origin/AliasSystem/params/base' into Al…
seisman 4efc0f3
Rename shading_offset/shading_fill to shade_offset/shade_fill
seisman 21a47b5
Improve the tests
seisman 1229204
Add one more test
seisman 30a795e
Merge branch 'main' into AliasSystem/params/base
seisman 3a4b369
Order parameters [skip ci]
seisman 9eb95fa
Use AbstractBaseClass
seisman c6bd16f
Fix issues after applying AbstractBaseClass
seisman 5bc36c7
Skip the doctest in Box
seisman e26873d
CI: Access DagsHub repository via an access token
seisman f298379
No need to check length of private variables like _innerborder and _s…
seisman bd57dc0
Rename private property _shading to _shade
seisman a337503
Merge branch 'dvc/debug' into AliasSystem/params/base
seisman 7582165
Merge branch 'main' into AliasSystem/params/base
seisman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
""" | ||
Classes for common parameters in PyGMT. | ||
""" | ||
|
||
from pygmt.params.box import Box |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
""" | ||
Base class for common parameters shared in PyGMT. | ||
""" | ||
|
||
from abc import ABC, abstractmethod | ||
|
||
|
||
class BaseParam(ABC): | ||
""" | ||
Base class for parameters in PyGMT. | ||
To define a new parameter class, inherit from this class and define the attributes | ||
that correspond to the parameters you want to include. | ||
The class should also implement the ``_aliases`` property, which returns a list of | ||
``Alias`` objects. Each ``Alias`` object represents a parameter and its value, and | ||
the ``__str__`` method will concatenate these values into a single string that can | ||
be passed to GMT. | ||
Optionally, you can override the ``_validate`` method to perform any necessary | ||
validation on the parameters after initialization. | ||
Examples | ||
-------- | ||
>>> from typing import Any | ||
>>> import dataclasses | ||
>>> from pygmt.params.base import BaseParam | ||
>>> from pygmt.alias import Alias | ||
>>> | ||
>>> @dataclasses.dataclass(repr=False) | ||
... class Test(BaseParam): | ||
... par1: Any = None | ||
... par2: Any = None | ||
... par3: Any = None | ||
... | ||
... @property | ||
... def _aliases(self): | ||
... return [ | ||
... Alias(self.par1), | ||
... Alias(self.par2, prefix="+a"), | ||
... Alias(self.par3, prefix="+b", sep="/"), | ||
... ] | ||
>>> var = Test(par1="val1") | ||
>>> str(var) | ||
'val1' | ||
>>> repr(var) | ||
"Test(par1='val1')" | ||
>>> var = Test(par1="val1", par2="val2", par3=("val3a", "val3b")) | ||
>>> str(var) | ||
'val1+aval2+bval3a/val3b' | ||
>>> repr(var) | ||
"Test(par1='val1', par2='val2', par3=('val3a', 'val3b'))" | ||
""" | ||
|
||
def __post_init__(self): | ||
""" | ||
Post-initialization method to _validate the _aliases property. | ||
""" | ||
self._validate() | ||
|
||
def _validate(self): # noqa: B027 | ||
""" | ||
Validate the parameters of the object. | ||
Optional method but can be overridden in subclasses to perform any necessary | ||
validation on the parameters. | ||
""" | ||
|
||
@property | ||
@abstractmethod | ||
def _aliases(self): | ||
""" | ||
List of Alias objects representing the parameters of this class. | ||
Must be implemented in subclasses to define the parameters and their aliases. | ||
""" | ||
|
||
def __str__(self): | ||
""" | ||
String representation of the object that can be passed to GMT directly. | ||
""" | ||
return "".join( | ||
[alias._value for alias in self._aliases if alias._value is not None] | ||
) | ||
|
||
def __repr__(self): | ||
""" | ||
String representation of the object. | ||
""" | ||
params = ", ".join( | ||
f"{k}={v!r}" | ||
for k, v in vars(self).items() | ||
if v is not None and v is not False | ||
) | ||
return f"{self.__class__.__name__}({params})" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
""" | ||
The Box class for specifying the box around GMT embellishments. | ||
""" | ||
|
||
import dataclasses | ||
from collections.abc import Sequence | ||
|
||
from pygmt.alias import Alias | ||
from pygmt.exceptions import GMTInvalidInput, GMTValueError | ||
from pygmt.helpers import is_nonstr_iter | ||
from pygmt.params.base import BaseParam | ||
|
||
__doctest_skip__ = ["Box"] | ||
|
||
|
||
@dataclasses.dataclass(repr=False) | ||
class Box(BaseParam): | ||
""" | ||
Class for specifying the box around GMT embellishments. | ||
|
||
Attributes | ||
---------- | ||
clearance | ||
Set clearances between the embellishment and the box border. It can be either a | ||
scalar value or a sequence of two/four values. | ||
|
||
- a scalar value means a uniform clearance in all four directions. | ||
- a sequence of two values means separate clearances in x- and y-directions. | ||
- a sequence of four values means separate clearances for left/right/bottom/top. | ||
fill | ||
Fill for the box [Default is no fill]. | ||
inner_gap | ||
Gap between the outer and inner borders [Default is ``"2p"``]. | ||
inner_pen | ||
Pen attributes for the inner border [Default to :gmt-term:`MAP_DEFAULT_PEN`]. | ||
pen | ||
Pen attributes for the box outline. | ||
radius | ||
Draw a rounded rectangular border instead of sharp. Passing a value with unit | ||
to control the corner radius [Default is ``"6p"``]. | ||
shade_offset | ||
Place an offset background shaded region behind the box. A sequence of two | ||
values (dx, dy) indicates the shift relative to the foreground frame [Default is | ||
``("4p", "-4p")``]. | ||
shade_fill | ||
Fill for the shaded region [Default is ``"gray50"``]. | ||
|
||
Examples | ||
-------- | ||
>>> import pygmt | ||
>>> from pygmt.params import Box | ||
>>> fig = pygmt.Figure() | ||
>>> fig.logo(box=Box(pen="1p", radius="5p", shade_offset=("5p", "5p"))) | ||
>>> fig.show() | ||
""" | ||
|
||
clearance: float | str | Sequence[float | str] | None = None | ||
fill: str | None = None | ||
inner_gap: float | str | None = None | ||
inner_pen: str | None = None | ||
pen: str | None = None | ||
radius: str | bool = False | ||
shade_offset: Sequence[float | str] | None = None | ||
shade_fill: str | None = None | ||
|
||
def _validate(self): | ||
""" | ||
Validate the parameters. | ||
""" | ||
# inner_pen is required when inner_gap is set. | ||
if self.inner_gap is not None and self.inner_pen is None: | ||
msg = "Parameter 'inner_pen' is required when 'inner_gap' is set." | ||
raise GMTInvalidInput(msg) | ||
|
||
# shade_offset must be a sequence of two values or None. | ||
if self.shade_offset and not ( | ||
is_nonstr_iter(self.shade_offset) and len(self.shade_offset) == 2 | ||
): | ||
raise GMTValueError( | ||
self.shade_offset, | ||
description="value for parameter 'shade_offset'", | ||
reason="Must be a sequence of two values (dx, dy) or None.", | ||
) | ||
|
||
@property | ||
def _innerborder(self) -> list[str | float] | None: | ||
""" | ||
Inner border of the box, formatted as a list of 1-2 values, or None. | ||
""" | ||
return [v for v in (self.inner_gap, self.inner_pen) if v is not None] or None | ||
|
||
@property | ||
def _shade(self) -> list[str | float] | None: | ||
""" | ||
Shading for the box, formatted as a list of 1-3 values, or None. | ||
""" | ||
_shade_offset = self.shade_offset or [] | ||
return [v for v in (*_shade_offset, self.shade_fill) if v is not None] or None | ||
|
||
@property | ||
def _aliases(self): | ||
""" | ||
Aliases for the parameter. | ||
""" | ||
return [ | ||
Alias(self.clearance, name="clearance", prefix="+c", sep="/", size=(2, 4)), | ||
Alias(self.fill, name="fill", prefix="+g"), | ||
Alias(self._innerborder, name="inner_gap/inner_pen", prefix="+i", sep="/"), | ||
Alias(self.pen, name="pen", prefix="+p"), | ||
Alias(self.radius, name="radius", prefix="+r"), | ||
Alias(self._shade, name="shade_offset/shade_fill", prefix="+s", sep="/"), | ||
] |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.