Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Co-authored-by: Dongdong Tian <[email protected]>
Co-authored-by: Wei Ji <[email protected]>
  • Loading branch information
3 people authored and Josh Sixsmith committed Dec 21, 2022
1 parent 0b2865d commit fc3babd
Show file tree
Hide file tree
Showing 8 changed files with 276 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Plotting data and laying out the map:
Figure.plot3d
Figure.set_panel
Figure.shift_origin
Figure.solar
Figure.subplot
Figure.text

Expand Down
48 changes: 48 additions & 0 deletions examples/gallery/embellishments/solar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""
Day-night terminator line and twilights
---------------------------------------
Use :meth:`pygmt.Figure.solar` to show the different transition stages between daytime
and nightime. The parameter ``terminator`` is used to set the twilight stage, and can be
either 'day-night' (brightest), 'civil', 'nautical', or 'astronomical' (darkest). Refer
to https://en.wikipedia.org/wiki/Twilight for more information.
"""
import datetime

import pygmt

fig = pygmt.Figure()
# Create a figure showing the global region on a Mollweide projection
# Land color is set to dark green and water color is set to light blue
fig.coast(region="d", projection="W0/15c", land="darkgreen", water="lightblue")
# Set a time for the day-night terminator and twilights, 1700 UTC on January 1, 2000
terminator_datetime = datetime.datetime(
year=2000, month=1, day=1, hour=17, minute=0, second=0
)
# Set the pen line to be 0.5p thick
# Set the fill for the night area to be navy blue at different transparency levels
fig.solar(
terminator="day_night",
terminator_datetime=terminator_datetime,
fill="navyblue@95",
pen="0.5p",
)
fig.solar(
terminator="civil",
terminator_datetime=terminator_datetime,
fill="navyblue@85",
pen="0.5p",
)
fig.solar(
terminator="nautical",
terminator_datetime=terminator_datetime,
fill="navyblue@80",
pen="0.5p",
)
fig.solar(
terminator="astronomical",
terminator_datetime=terminator_datetime,
fill="navyblue@80",
pen="0.5p",
)
fig.show()
1 change: 1 addition & 0 deletions pygmt/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ def _repr_html_(self):
plot,
plot3d,
set_panel,
solar,
subplot,
text,
)
1 change: 1 addition & 0 deletions pygmt/src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from pygmt.src.meca import meca
from pygmt.src.plot import plot
from pygmt.src.plot3d import plot3d
from pygmt.src.solar import solar
from pygmt.src.subplot import set_panel, subplot
from pygmt.src.surface import surface
from pygmt.src.text import text_ as text # "text" is an argument within "text_"
Expand Down
97 changes: 97 additions & 0 deletions pygmt/src/solar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
"""
solar - Plot day-night terminators and twilight.
"""
import pandas as pd
from pygmt.clib import Session
from pygmt.exceptions import GMTInvalidInput
from pygmt.helpers import build_arg_string, fmt_docstring, kwargs_to_strings, use_alias


@fmt_docstring
@use_alias(
B="frame",
G="fill",
J="projection",
R="region",
U="timestamp",
V="verbose",
W="pen",
X="xshift",
Y="yshift",
c="panel",
p="perspective",
t="transparency",
)
@kwargs_to_strings(R="sequence", c="sequence_comma", p="sequence")
def solar(self, terminator="d", terminator_datetime=None, **kwargs):
r"""
Plot day-light terminators or twilights.
This function plots the day-night terminator. Alternatively, it can plot
the terminators for civil twilight, nautical twilight, or astronomical
twilight.
Full parameter list at :gmt-docs:`solar.html`
{aliases}
Parameters
----------
terminator : str
Set the type of terminator displayed. Valid arguments are
**day_night**, **civil**, **nautical**, and **astronomical**, which
can be set with either the full name or the first letter of the name.
[Default is **day_night**]
Refer to https://en.wikipedia.org/wiki/Twilight for the definitions of
different types of twilight.
terminator_datetime : str or datetime object
Set the UTC date and time of the displayed terminator. It can be
passed as a string or Python datetime object.
[Default is the current UTC date and time]
{R}
{J}
{B}
fill : str
Color or pattern for filling of terminators.
pen : str
Set pen attributes for lines. The default pen
is ``default,black,solid``.
{U}
{V}
{XY}
{c}
{p}
{t}
"""

kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access
if "T" in kwargs:
raise GMTInvalidInput(
"Use 'terminator' and 'terminator_datetime' instead of 'T'."
)
if terminator not in [
"day_night",
"civil",
"nautical",
"astronomical",
"d",
"c",
"n",
"a",
]:
raise GMTInvalidInput(
f"Unrecognized solar terminator type '{terminator}'. Valid values "
"are 'day_night', 'civil', 'nautical', and 'astronomical'."
)
kwargs["T"] = terminator[0]
if terminator_datetime:
try:
datetime_string = pd.to_datetime(terminator_datetime).strftime(
"%Y-%m-%dT%H:%M:%S.%f"
)
except ValueError as verr:
raise GMTInvalidInput("Unrecognized datetime format.") from verr
kwargs["T"] += f"+d{datetime_string}"
with Session() as lib:
lib.call_module("solar", build_arg_string(kwargs))
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
outs:
- md5: 0a7f4959b500b6fa3a560a6368db0f90
size: 25982
path: test_solar_set_terminator_datetime.png
4 changes: 4 additions & 0 deletions pygmt/tests/baseline/test_solar_terminators.png.dvc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
outs:
- md5: 54c92bea64e0fc76c62601cb6131f22e
size: 44160
path: test_solar_terminators.png
120 changes: 120 additions & 0 deletions pygmt/tests/test_solar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""
Tests for solar.
"""
import datetime

import pytest
from pygmt import Figure
from pygmt.exceptions import GMTInvalidInput


@pytest.mark.mpl_image_compare
def test_solar_terminators():
"""
Test passing the solar argument with a time string and no terminator type
to confirm the default terminator type.
"""
fig = Figure()
fig.basemap(region="d", projection="W0/15c", frame="a")
fig.solar(
terminator="d",
pen="1p,blue",
terminator_datetime="1990-02-17 04:25:00",
)
fig.solar(
terminator="a",
pen="1p,red",
terminator_datetime="1990-02-17 04:25:00",
)
fig.solar(
terminator="c",
pen="1p,green",
terminator_datetime="1990-02-17 04:25:00",
)
fig.solar(
terminator="n",
pen="1p,yellow",
terminator_datetime="1990-02-17 04:25:00",
)
return fig


@pytest.mark.mpl_image_compare(filename="test_solar_set_terminator_datetime.png")
@pytest.mark.parametrize(
"terminator_datetime",
[
pytest.param("1990-02-17 04:25:00", id="terminator_datetime_string"),
datetime.datetime(year=1990, month=2, day=17, hour=4, minute=25, second=0),
],
)
def test_solar_set_terminator_datetime(terminator_datetime):
"""
Test passing the solar argument with the day_night terminator and a
datetime string.
"""
fig = Figure()
fig.solar(
region="d",
projection="W0/15c",
frame="a",
terminator="day_night",
terminator_datetime=terminator_datetime,
)
return fig


def test_invalid_terminator_type():
"""
Test if solar fails when it receives an invalid terminator type.
"""
fig = Figure()
with pytest.raises(GMTInvalidInput):
fig.solar(
region="d",
projection="W0/15c",
frame="a",
terminator="invalid",
)


def test_invalid_parameter():
"""
Test if solar fails when it receives a GMT argument for 'T' instead of the
PyGMT arguments for 'terminator' and 'terminator_datetime'.
"""
fig = Figure()
with pytest.raises(GMTInvalidInput):
# Use single-letter option 'T' for testing
fig.solar(
region="d", projection="W0/15c", frame="a", T="d+d1990-02-17T04:25:00"
)


def test_invalid_datetime():
"""
Test if solar fails when it receives an invalid datetime string.
"""
fig = Figure()
with pytest.raises(GMTInvalidInput):
fig.solar(
region="d",
projection="W0/15c",
frame="a",
terminator_datetime="199A-02-17 04:25:00",
)


@pytest.mark.mpl_image_compare(filename="test_solar_set_terminator_datetime.png")
def test_solar_default_terminator():
"""
Test passing the solar argument with a time string and no terminator type
to confirm the default terminator type.
"""
fig = Figure()
fig.solar(
region="d",
projection="W0/15c",
frame="a",
terminator_datetime="1990-02-17 04:25:00",
)
return fig

0 comments on commit fc3babd

Please sign in to comment.