diff --git a/examples/tutorials/advanced/cartesian_histograms.py b/examples/tutorials/advanced/cartesian_histograms.py index b97881f6c37..5b66707befd 100644 --- a/examples/tutorials/advanced/cartesian_histograms.py +++ b/examples/tutorials/advanced/cartesian_histograms.py @@ -345,9 +345,9 @@ histtype=0, # Calculate the bar width in respect to the bin width, here for two data sets half # of the bin width - # Offset ("+o") the bars to align each bar with the left limit of the corresponding - # bin - bar_width=f"{binwidth / 2}+o-{binwidth / 4}", + bar_width=binwidth / 2, + # Offset the bars to align each bar with the left limit of the corresponding bin + bar_offset=-binwidth / 4, label="data01", ) @@ -358,7 +358,8 @@ fill="orange", pen="1p,darkgray,solid", histtype=0, - bar_width=f"{binwidth / 2}+o{binwidth / 4}", + bar_width=binwidth / 2, + bar_offset=binwidth / 4, label="data02", ) diff --git a/pygmt/src/histogram.py b/pygmt/src/histogram.py index f1aa068a484..5b52ddac0eb 100644 --- a/pygmt/src/histogram.py +++ b/pygmt/src/histogram.py @@ -6,8 +6,9 @@ from typing import Literal from pygmt._typing import PathLike, TableLike -from pygmt.alias import AliasSystem +from pygmt.alias import Alias, AliasSystem from pygmt.clib import Session +from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( build_arg_list, deprecate_parameter, @@ -23,7 +24,6 @@ A="horizontal", C="cmap", D="annotate", - E="bar_width", F="center", G="fill", L="extreme", @@ -41,10 +41,12 @@ w="wrap", ) @kwargs_to_strings(T="sequence") -def histogram( +def histogram( # noqa: PLR0913 self, data: PathLike | TableLike, projection: str | None = None, + bar_width: float | str | None = None, + bar_offset: float | str | None = None, frame: str | Sequence[str] | bool = False, region: Sequence[float | str] | str | None = None, verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"] @@ -62,6 +64,7 @@ def histogram( $aliases - B = frame + - E = bar_width, bar_offset - J = projection - R = region - V = verbose @@ -91,15 +94,14 @@ def histogram( annotation font; use **+o** to change the offset between bar and label [Default is ``"6p"``]; use **+r** to rotate the labels from horizontal to vertical. - bar_width : float or str - *width*\ [**+o**\ *offset*]. + bar_width Use an alternative histogram bar width than the default set via - ``series``, and optionally shift all bars by an *offset*. Here - *width* is either an alternative width in data units, or the user may - append a valid plot dimension unit (**c**\|\ **i**\|\ **p**) for a - fixed dimension instead. Optionally, all bins may be shifted along the - axis by *offset*. As for *width*, it may be given in data units of - plot dimension units by appending the relevant unit. + ``series``. Give either an alternative width in data units, or the user + may append a valid plot dimension unit (**c**\|\ **i**\|\ **p**) for a + fixed dimension instead. + bar_offset + Shift all bars along the axis by *offset*. It may be given in data units + of plot dimension units by appending the relevant unit. center : bool Center bin on each value. [Default is left edge]. distribution : bool, float, or str @@ -159,7 +161,16 @@ def histogram( """ self._activate_figure() - aliasdict = AliasSystem().add_common( + if bar_offset is not None and bar_width is None: + msg = "Setting 'bar_offset' requires setting 'bar_width'." + raise GMTInvalidInput(msg) + + aliasdict = AliasSystem( + E=[ + Alias(bar_width, name="bar_width"), + Alias(bar_offset, name="bar_offset", prefix="+o"), + ], + ).add_common( B=frame, J=projection, R=region, diff --git a/pygmt/tests/test_histogram.py b/pygmt/tests/test_histogram.py index 8a85ffd4666..3f1a78f04b0 100644 --- a/pygmt/tests/test_histogram.py +++ b/pygmt/tests/test_histogram.py @@ -5,6 +5,7 @@ import pandas as pd import pytest from pygmt import Figure +from pygmt.exceptions import GMTInvalidInput @pytest.fixture(scope="module", name="data", params=[list, pd.Series]) @@ -32,3 +33,20 @@ def test_histogram(data): fill="green", ) return fig + + +def test_histogram_baroffset(data): + """ + Test passing bar_offset requires bar_width. + """ + fig = Figure() + with pytest.raises(GMTInvalidInput): + fig.histogram( + data=data, + projection="X10c/10c", + region=[0, 9, 0, 6], + series=1, + frame="a", + fill="green", + bar_offset=0.25, + )