From c7cb217c9f281aeaa5fd6222ca959790b6d4a685 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 7 Oct 2023 16:01:58 +0800 Subject: [PATCH 1/9] Figure.text: Support passing in a list of angle/font/justify values --- pygmt/src/text.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/pygmt/src/text.py b/pygmt/src/text.py index cd7dabcc3d5..de516086431 100644 --- a/pygmt/src/text.py +++ b/pygmt/src/text.py @@ -39,9 +39,6 @@ @kwargs_to_strings( R="sequence", textfiles="sequence_space", - angle="sequence_comma", - font="sequence_comma", - justify="sequence_comma", c="sequence_comma", p="sequence", ) @@ -203,25 +200,34 @@ def text_( ): kwargs.update({"F": ""}) + extra_arrays = [] if angle is True: kwargs["F"] += "+a" + elif is_nonstr_iter(angle): + kwargs["F"] += "+a" + extra_arrays.append(np.atleast_1d(angle)) elif isinstance(angle, (int, float, str)): kwargs["F"] += f"+a{str(angle)}" if font is True: kwargs["F"] += "+f" + elif is_nonstr_iter(font): + kwargs["F"] += "+f" + extra_arrays.append(np.atleast_1d(font).astype(str)) elif isinstance(font, str): kwargs["F"] += f"+f{font}" if justify is True: kwargs["F"] += "+j" + elif is_nonstr_iter(justify): + kwargs["F"] += "+j" + extra_arrays.append(np.atleast_1d(justify).astype(str)) elif isinstance(justify, str): kwargs["F"] += f"+j{justify}" if isinstance(position, str): kwargs["F"] += f"+c{position}+t{text}" - extra_arrays = [] # If an array of transparency is given, GMT will read it from # the last numerical column per data record. if kwargs.get("t") is not None and is_nonstr_iter(kwargs["t"]): From 17fb9dbc39ac1fa22f09a713de38b379fec3f453 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 7 Oct 2023 16:16:13 +0800 Subject: [PATCH 2/9] Simplify the handling of angle/font/justify --- pygmt/src/text.py | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/pygmt/src/text.py b/pygmt/src/text.py index de516086431..51967365580 100644 --- a/pygmt/src/text.py +++ b/pygmt/src/text.py @@ -201,29 +201,17 @@ def text_( kwargs.update({"F": ""}) extra_arrays = [] - if angle is True: - kwargs["F"] += "+a" - elif is_nonstr_iter(angle): - kwargs["F"] += "+a" - extra_arrays.append(np.atleast_1d(angle)) - elif isinstance(angle, (int, float, str)): - kwargs["F"] += f"+a{str(angle)}" - - if font is True: - kwargs["F"] += "+f" - elif is_nonstr_iter(font): - kwargs["F"] += "+f" - extra_arrays.append(np.atleast_1d(font).astype(str)) - elif isinstance(font, str): - kwargs["F"] += f"+f{font}" - - if justify is True: - kwargs["F"] += "+j" - elif is_nonstr_iter(justify): - kwargs["F"] += "+j" - extra_arrays.append(np.atleast_1d(justify).astype(str)) - elif isinstance(justify, str): - kwargs["F"] += f"+j{justify}" + for arg, flag in [(angle, "+a"), (font, "+f"), (justify, "+j")]: + if arg is True: + kwargs["F"] += flag + elif is_nonstr_iter(arg): + kwargs["F"] += flag + if flag == "+a": # angle is numeric type + extra_arrays.append(np.atleast_1d(arg)) # numeric + else: # font or justify is str type + extra_arrays.append(np.atleast_1d(arg).astype(str)) + elif isinstance(arg, (int, float, str)): + kwargs["F"] += f"{flag}{arg}" if isinstance(position, str): kwargs["F"] += f"+c{position}+t{text}" From 3b2ebfa67b9adb8ce981fb9ce833787a111c422b Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 7 Oct 2023 16:24:08 +0800 Subject: [PATCH 3/9] Improve the docstrings --- pygmt/src/text.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pygmt/src/text.py b/pygmt/src/text.py index 51967365580..347666ad068 100644 --- a/pygmt/src/text.py +++ b/pygmt/src/text.py @@ -94,12 +94,12 @@ def text_( of the map. text : str or 1-D array The text string, or an array of strings to plot on the figure. - angle: int, float, str or bool + angle: int, float, str, bool or list Set the angle measured in degrees counter-clockwise from horizontal (e.g. 30 sets the text at 30 degrees). If no angle is explicitly given (i.e. ``angle=True``) then the input to ``textfiles`` must have this as a column. - font : str or bool + font : str, bool or list of str Set the font specification with format *size*\ ,\ *font*\ ,\ *color* where *size* is text size in points, *font* is the font to use, and *color* sets the font color. For example, @@ -107,7 +107,7 @@ def text_( font. If no font info is explicitly given (i.e. ``font=True``), then the input to ``textfiles`` must have this information in one of its columns. - justify : str or bool + justify : str, bool or list of str Set the alignment which refers to the part of the text string that will be mapped onto the (x, y) point. Choose a two-letter combination of **L**, **C**, **R** (for left, center, or right) and From 9e8e9c865b5f8b71e91e05485044808de689a54e Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 7 Oct 2023 17:05:02 +0800 Subject: [PATCH 4/9] Add a test for passing a justify array --- pygmt/tests/test_text.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pygmt/tests/test_text.py b/pygmt/tests/test_text.py index 9a8b1cf6663..87a7063da66 100644 --- a/pygmt/tests/test_text.py +++ b/pygmt/tests/test_text.py @@ -311,6 +311,24 @@ def test_text_angle_font_justify_from_textfile(): return fig +@pytest.mark.mpl_image_compare(filename="test_text_position.png") +def test_text_justify_array(region): + """ + Test passing an array of justify codes. + + Re-use the baseline image from test_text_position(). + """ + fig = Figure() + fig.basemap(region=region, projection="x1c", frame="a") + fig.text( + x=[0, 2.5, 5.0, 0, 2.5, 5.0, 0, 2.5, 5.0], + y=[0, 0, 0, 1.25, 1.25, 1.25, 2.5, 2.5, 2.5], + justify=["BL", "BC", "BR", "ML", "MC", "MR", "TL", "TC", "TR"], + text=["BL", "BC", "BR", "ML", "C M", "MR", "TL", "TC", "TR"], + ) + return fig + + @pytest.mark.mpl_image_compare def test_text_transparency(): """ From 538780a945c4fd6a2c00d75338e2747a7cfaa609 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 7 Oct 2023 17:36:00 +0800 Subject: [PATCH 5/9] Fix the bug when concatenating strings arrays with spaces --- pygmt/clib/session.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index ffe675e1bc4..8db686812c1 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -1291,9 +1291,7 @@ def virtualfile_from_vectors(self, *vectors): if len(string_arrays) == 1: strings = string_arrays[0] elif len(string_arrays) > 1: - strings = np.apply_along_axis( - func1d=" ".join, axis=0, arr=string_arrays - ) + strings = np.array([" ".join(vals) for vals in zip(*string_arrays)]) strings = np.asanyarray(a=strings, dtype=str) self.put_strings( dataset, family="GMT_IS_VECTOR|GMT_IS_DUPLICATE", strings=strings From 2359c04be359338d3f7fb3b9b15e1b1b01d9bac4 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 7 Oct 2023 21:03:48 +0800 Subject: [PATCH 6/9] Add one more test --- ...test_text_angle_justify_font_arrays.png.dvc | 5 +++++ pygmt/tests/test_text.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 pygmt/tests/baseline/test_text_angle_justify_font_arrays.png.dvc diff --git a/pygmt/tests/baseline/test_text_angle_justify_font_arrays.png.dvc b/pygmt/tests/baseline/test_text_angle_justify_font_arrays.png.dvc new file mode 100644 index 00000000000..2b23888fe67 --- /dev/null +++ b/pygmt/tests/baseline/test_text_angle_justify_font_arrays.png.dvc @@ -0,0 +1,5 @@ +outs: +- md5: c111539b0b5966eee4305f9485c85bd0 + size: 8208 + hash: md5 + path: test_text_angle_justify_font_arrays.png diff --git a/pygmt/tests/test_text.py b/pygmt/tests/test_text.py index 87a7063da66..0b79c2fde15 100644 --- a/pygmt/tests/test_text.py +++ b/pygmt/tests/test_text.py @@ -329,6 +329,24 @@ def test_text_justify_array(region): return fig +@pytest.mark.mpl_image_compare +def test_text_angle_justify_font_arrays(region): + """ + Test passing arrays of angle, justify and font. + """ + fig = Figure() + fig.basemap(region=region, projection="X5c/2.5c", frame=True) + fig.text( + x=[2.5, 2.5], + y=[1.0, 2.0], + angle=[30, 50], + justify=["TL", "BR"], + font=["15p,Helvetica-Bold,red", "5p,Times-Italic,blue"], + text=["TEXT1", "TEXT2 with spaces"], + ) + return fig + + @pytest.mark.mpl_image_compare def test_text_transparency(): """ From 3fa58be85c71237da55fa21a1ce73573278cc0e7 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 7 Oct 2023 21:10:56 +0800 Subject: [PATCH 7/9] Revert "Fix the bug when concatenating strings arrays with spaces" This reverts commit 538780a945c4fd6a2c00d75338e2747a7cfaa609. --- pygmt/clib/session.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pygmt/clib/session.py b/pygmt/clib/session.py index 8db686812c1..ffe675e1bc4 100644 --- a/pygmt/clib/session.py +++ b/pygmt/clib/session.py @@ -1291,7 +1291,9 @@ def virtualfile_from_vectors(self, *vectors): if len(string_arrays) == 1: strings = string_arrays[0] elif len(string_arrays) > 1: - strings = np.array([" ".join(vals) for vals in zip(*string_arrays)]) + strings = np.apply_along_axis( + func1d=" ".join, axis=0, arr=string_arrays + ) strings = np.asanyarray(a=strings, dtype=str) self.put_strings( dataset, family="GMT_IS_VECTOR|GMT_IS_DUPLICATE", strings=strings From bc89cb987354280ac9d861d4dabaf1e5da79be2e Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 7 Oct 2023 21:12:14 +0800 Subject: [PATCH 8/9] Fix linting issue --- pygmt/src/text.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/src/text.py b/pygmt/src/text.py index 347666ad068..ab6431b31f0 100644 --- a/pygmt/src/text.py +++ b/pygmt/src/text.py @@ -167,7 +167,7 @@ def text_( ``x``/``y`` and ``text``. {wrap} """ - # pylint: disable=too-many-branches + # pylint: disable=too-many-branches,too-many-locals kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access # Ensure inputs are either textfiles, x/y/text, or position/text From 54df98419093871c9a8fe870f42ab4ba6c32b693 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 7 Oct 2023 21:14:42 +0800 Subject: [PATCH 9/9] Update pygmt/src/text.py --- pygmt/src/text.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/src/text.py b/pygmt/src/text.py index ab6431b31f0..f7b51e072f5 100644 --- a/pygmt/src/text.py +++ b/pygmt/src/text.py @@ -207,7 +207,7 @@ def text_( elif is_nonstr_iter(arg): kwargs["F"] += flag if flag == "+a": # angle is numeric type - extra_arrays.append(np.atleast_1d(arg)) # numeric + extra_arrays.append(np.atleast_1d(arg)) else: # font or justify is str type extra_arrays.append(np.atleast_1d(arg).astype(str)) elif isinstance(arg, (int, float, str)):