Skip to content
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

Figure.plot: Add the "symbol" parameter to support plotting data points with varying symbols #1117

Merged
merged 19 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from 9 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
23 changes: 20 additions & 3 deletions pygmt/src/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
t="transparency",
)
@kwargs_to_strings(R="sequence", c="sequence_comma", i="sequence_comma", p="sequence")
def plot(self, x=None, y=None, data=None, sizes=None, direction=None, **kwargs):
def plot(
self, x=None, y=None, data=None, sizes=None, direction=None, symbol=None, **kwargs
):
r"""
Plot lines, polygons, and symbols in 2-D.

Expand Down Expand Up @@ -86,6 +88,8 @@ def plot(self, x=None, y=None, data=None, sizes=None, direction=None, **kwargs):
should be a list of two 1d arrays with the vector directions. These
can be angle and length, azimuth and length, or x and y components,
depending on the style options chosen.
symbol : 1d array
The symbols of the data points. Only valid if using ``x``/``y``.
{J}
{R}
straight_line : bool or str
Expand Down Expand Up @@ -206,15 +210,18 @@ def plot(self, x=None, y=None, data=None, sizes=None, direction=None, **kwargs):
kind = data_kind(data, x, y)

extra_arrays = []
if "S" in kwargs and kwargs["S"][0] in "vV" and direction is not None:
extra_arrays.extend(direction)
if "S" in kwargs and isinstance(kwargs["S"], str):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added isinstance(kwargs["S"], str) in case that the style parameter is True, False, None, int, or float.

if kwargs["S"][0] in "vV" and direction is not None:
extra_arrays.extend(direction)

if "G" in kwargs and not isinstance(kwargs["G"], str):
if kind != "vectors":
raise GMTInvalidInput(
"Can't use arrays for color if data is matrix or file."
)
extra_arrays.append(kwargs["G"])
del kwargs["G"]

if sizes is not None:
if kind != "vectors":
raise GMTInvalidInput(
Expand All @@ -231,6 +238,16 @@ def plot(self, x=None, y=None, data=None, sizes=None, direction=None, **kwargs):
extra_arrays.append(kwargs[flag])
kwargs[flag] = ""

if symbol is not None:
if "S" not in kwargs:
kwargs["S"] = True

if kind != "vectors":
raise GMTInvalidInput(
"Can't use arrays for symbol if data is matrix or file."
)
extra_arrays.append(symbol)

with Session() as lib:
# Choose how data will be passed in to the module
file_context = lib.virtualfile_from_data(
Expand Down
4 changes: 4 additions & 0 deletions pygmt/tests/baseline/test_plot_symbols.png.dvc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
outs:
- md5: 394a4e806a99234f239437252a99254c
size: 13759
path: test_plot_symbols.png
31 changes: 27 additions & 4 deletions pygmt/tests/test_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,23 @@ def test_plot_fail_no_data(data):
)


def test_plot_fail_color_size_intensity(data):
def test_plot_fail_1d_array_using_data(data):
"""
Should raise an exception if array color, sizes and intensity are used with
matrix.
Should raise an exception if array color, sizes, intensity and symbol are
used with matrix.
"""
fig = Figure()
kwargs = dict(data=data, region=region, projection="X10c", frame="afg")
with pytest.raises(GMTInvalidInput):
fig.plot(style="c0.2c", color=data[:, 2], **kwargs)
with pytest.raises(GMTInvalidInput):
fig.plot(style="cc", sizes=data[:, 2], color="red", **kwargs)
fig.plot(style="cc", color="red", sizes=data[:, 2], **kwargs)
with pytest.raises(GMTInvalidInput):
fig.plot(style="c0.2c", color="red", intensity=data[:, 2], **kwargs)
with pytest.raises(GMTInvalidInput):
fig.plot(
style="0.2c", color="red", symbol=np.full(len(data[:, 2]), "c"), **kwargs
)


@pytest.mark.mpl_image_compare
Expand Down Expand Up @@ -295,6 +299,25 @@ def test_plot_sizes_colors_transparencies():
return fig


@pytest.mark.mpl_image_compare
def test_plot_symbols(data, region):
"""
Plot the data using array-like symbols.
"""
fig = Figure()
fig.plot(
x=data[:, 0],
y=data[:, 1],
region=region,
projection="X4c",
color="blue",
sizes=np.full(len(data[:, 0]), 0.5),
symbol=np.full(len(data[:, 0]), "c"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment, this test is checking that plotting all symbols as circles (c) work. A better test would be to test a mix of symbols such as circles (c), triangles (t), squares (s), etc (like your example in #1076 (comment)).

frame="af",
)
return fig


@pytest.mark.mpl_image_compare
def test_plot_matrix(data):
"""
Expand Down