Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()
12 changes: 6 additions & 6 deletions pygmt/datasets/samples.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

def load_japan_quakes():
"""
Load a table of earthquakes around Japan as a pandas.Dataframe.
Load a table of earthquakes around Japan as a pandas.DataFrame.

Data is from the NOAA NGDC database. This is the ``@tut_quakes.ngdc``
dataset used in the GMT tutorials.
Expand All @@ -18,7 +18,7 @@ def load_japan_quakes():

Returns
-------
data : pandas.Dataframe
data : pandas.DataFrame
The data table. Columns are year, month, day, latitude, longitude,
depth (in km), and magnitude of the earthquakes.
"""
Expand Down Expand Up @@ -49,7 +49,7 @@ def load_ocean_ridge_points():

Returns
-------
data : pandas.Dataframe
data : pandas.DataFrame
The data table. Columns are longitude and latitude.
"""
fname = which("@ridge.txt", download="c")
Expand All @@ -72,7 +72,7 @@ def load_sample_bathymetry():

Returns
-------
data : pandas.Dataframe
data : pandas.DataFrame
The data table. Columns are longitude, latitude, and bathymetry.
"""
fname = which("@tut_ship.xyz", download="c")
Expand All @@ -84,7 +84,7 @@ def load_sample_bathymetry():

def load_usgs_quakes():
"""
Load a table of global earthquakes form the USGS as a pandas.Dataframe.
Load a table of global earthquakes form the USGS as a pandas.DataFrame.

This is the ``@usgs_quakes_22.txt`` dataset used in the GMT tutorials.

Expand All @@ -94,7 +94,7 @@ def load_usgs_quakes():

Returns
-------
data : pandas.Dataframe
data : pandas.DataFrame
The data table. Use ``print(data.describe())`` to see the available
columns.
"""
Expand Down
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