From d1c9ce4c05d07487375e274946a6664f74090240 Mon Sep 17 00:00:00 2001 From: czertyaka Date: Sat, 12 Oct 2024 14:22:21 +0500 Subject: [PATCH 01/10] Added scale_style parameter --- matplotlib_scalebar/scalebar.py | 56 ++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/matplotlib_scalebar/scalebar.py b/matplotlib_scalebar/scalebar.py index 92382b1..65911aa 100644 --- a/matplotlib_scalebar/scalebar.py +++ b/matplotlib_scalebar/scalebar.py @@ -23,6 +23,7 @@ - scalebar.box_alpha - scalebar.scale_loc - scalebar.label_loc + - scalebar.scale_style See the class documentation (:class:`.Scalebar`) for a description of the parameters. @@ -86,6 +87,9 @@ _VALID_ROTATIONS = ["horizontal", "vertical"] _validate_rotation = ValidateInStrings("rotation", _VALID_ROTATIONS, ignorecase=True) +_VALID_BOX_STYLES = ["solid", "geography"] +_validate_scale_style = ValidateInStrings("scale_style", _VALID_BOX_STYLES, ignorecase=True) + def _validate_legend_loc(loc): rc = matplotlib.RcParams() @@ -108,6 +112,7 @@ def _validate_legend_loc(loc): "scalebar.scale_loc": ["bottom", _validate_scale_loc], "scalebar.label_loc": ["top", _validate_label_loc], "scalebar.rotation": ["horizontal", _validate_rotation], + "scalebar.scale_style": ["solid", _validate_scale_style], } ) @@ -176,6 +181,7 @@ def __init__( box_alpha=None, scale_loc=None, label_loc=None, + scale_style=None, font_properties=None, label_formatter=None, scale_formatter=None, @@ -276,6 +282,10 @@ def __init__( If ``none`` the label is not shown. :type label_loc: :class:`str` + :arg scale_style: style of box + (default: rcParams['scalebar.scale_style'] or ``solid``) + :type scale_style: :class:`str` + :arg font_properties: font properties of the label text, specified either as dict or `fontconfig `_ pattern (XML). @@ -349,6 +359,7 @@ def __init__( self.box_alpha = box_alpha self.scale_loc = scale_loc self.label_loc = label_loc + self.scale_style = scale_style self.scale_formatter = scale_formatter self.font_properties = font_properties self.fixed_value = fixed_value @@ -381,6 +392,27 @@ def _calculate_exact_length(self, value, units): newvalue = self.dimension.convert(value, units, self.units) return newvalue / self.dx + def draw_solid_rect(self, rotation, length_px, width_px, color): + # Create scale bar + if rotation == "horizontal": + return Rectangle( + (0, 0), + length_px, + width_px, + fill=True, + facecolor=color, + edgecolor="none", + ) + else: + return Rectangle( + (0, 0), + width_px, + length_px, + fill=True, + facecolor=color, + edgecolor="none", + ) + def draw(self, renderer, *args, **kwargs): if not self.get_visible(): return @@ -422,6 +454,7 @@ def _get_value(attr, default): box_alpha = _get_value("box_alpha", 1.0) scale_loc = _get_value("scale_loc", "bottom").lower() label_loc = _get_value("label_loc", "top").lower() + scale_style = _get_value("scale_style", "solid") font_properties = self.font_properties fixed_value = self.fixed_value fixed_units = self.fixed_units or self.units @@ -455,25 +488,10 @@ def _get_value(attr, default): width_px = abs(ylim[1] - ylim[0]) * width_fraction - # Create scale bar - if rotation == "horizontal": - scale_rect = Rectangle( - (0, 0), - length_px, - width_px, - fill=True, - facecolor=color, - edgecolor="none", - ) - else: - scale_rect = Rectangle( - (0, 0), - width_px, - length_px, - fill=True, - facecolor=color, - edgecolor="none", - ) + if not scale_style or scale_style == "solid": + scale_rect = self.draw_solid_rect(rotation, length_px, width_px, color) + elif scale_style == "geography": + pass scale_bar_box = AuxTransformBox(ax.transData) scale_bar_box.add_artist(scale_rect) From b1385bce60844c02d423238f4ba9b632679a126b Mon Sep 17 00:00:00 2001 From: czertyaka Date: Sat, 12 Oct 2024 14:39:54 +0500 Subject: [PATCH 02/10] Fixed variable name; added setter and getter for _scale_style --- matplotlib_scalebar/scalebar.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/matplotlib_scalebar/scalebar.py b/matplotlib_scalebar/scalebar.py index 65911aa..b59b3a1 100644 --- a/matplotlib_scalebar/scalebar.py +++ b/matplotlib_scalebar/scalebar.py @@ -87,8 +87,8 @@ _VALID_ROTATIONS = ["horizontal", "vertical"] _validate_rotation = ValidateInStrings("rotation", _VALID_ROTATIONS, ignorecase=True) -_VALID_BOX_STYLES = ["solid", "geography"] -_validate_scale_style = ValidateInStrings("scale_style", _VALID_BOX_STYLES, ignorecase=True) +_VALID_SCALE_STYLES = ["solid", "geography"] +_validate_scale_style = ValidateInStrings("scale_style", _VALID_SCALE_STYLES, ignorecase=True) def _validate_legend_loc(loc): @@ -777,6 +777,19 @@ def set_scale_formatter(self, scale_formatter): scale_formatter = property(get_scale_formatter, set_scale_formatter) + def get_scale_style(self): + return self._scale_style + + def set_scale_style(self, scale_style): + if scale_style is not None and scale_style not in _VALID_SCALE_STYLES: + raise ValueError( + f"Unknown scale_style: {scale_style}. " + f"Valid locations: {', '.join(_VALID_SCALE_STYLES)}" + ) + self._scale_style = scale_style + + scale_style = property(get_scale_style, set_scale_style) + def get_label_formatter(self): warnings.warn( "The get_label_formatter method is deprecated. " From 560a3aa7d27aaba266ad7a0de2c1288705120b5b Mon Sep 17 00:00:00 2001 From: czertyaka Date: Sat, 12 Oct 2024 15:33:49 +0500 Subject: [PATCH 03/10] Added geography style implementation for horizontal rotation --- matplotlib_scalebar/scalebar.py | 62 ++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/matplotlib_scalebar/scalebar.py b/matplotlib_scalebar/scalebar.py index b59b3a1..de6ec8e 100644 --- a/matplotlib_scalebar/scalebar.py +++ b/matplotlib_scalebar/scalebar.py @@ -40,6 +40,7 @@ # Standard library modules. import bisect import warnings +import math # Third party modules. import matplotlib @@ -60,6 +61,7 @@ AnchoredOffsetbox, ) from matplotlib.patches import Rectangle +from matplotlib.colors import to_rgba # Local modules. from matplotlib_scalebar.dimension import ( @@ -395,7 +397,7 @@ def _calculate_exact_length(self, value, units): def draw_solid_rect(self, rotation, length_px, width_px, color): # Create scale bar if rotation == "horizontal": - return Rectangle( + rec = Rectangle( (0, 0), length_px, width_px, @@ -404,7 +406,7 @@ def draw_solid_rect(self, rotation, length_px, width_px, color): edgecolor="none", ) else: - return Rectangle( + rec = Rectangle( (0, 0), width_px, length_px, @@ -412,6 +414,49 @@ def draw_solid_rect(self, rotation, length_px, width_px, color): facecolor=color, edgecolor="none", ) + return [rec] + + def draw_geography_rect( + self, + rotation, + length_px, + width_px, + color, + value, + ): + def calc_best_step(length): + capacity = int(math.floor(math.log10(length))) + step = math.pow(10, capacity) + if step * 2 > length: + step = step / 2 + return step + + def invert_color(color_name): + rgb = to_rgba(color_name) + return (1 - rgb[0], 1 - rgb[1], 1 - rgb[2]) + + step = calc_best_step(value) + step_px = step * length_px / value + second_color = invert_color(color) + + filled_px = 0 + rectangles = [] + current_color = color + while filled_px < length_px: + rec_step_px = step_px if filled_px + step_px <= length_px else length_px - filled_px + rectangles.append( + Rectangle( + (filled_px, 0), + rec_step_px, + width_px, + fill=True, + facecolor=current_color, + edgecolor=color + ) + ) + current_color = second_color if current_color == color else color + filled_px += rec_step_px + return rectangles def draw(self, renderer, *args, **kwargs): if not self.get_visible(): @@ -489,12 +534,19 @@ def _get_value(attr, default): width_px = abs(ylim[1] - ylim[0]) * width_fraction if not scale_style or scale_style == "solid": - scale_rect = self.draw_solid_rect(rotation, length_px, width_px, color) + scale_rects = self.draw_solid_rect(rotation, length_px, width_px, color) elif scale_style == "geography": - pass + scale_rects = self.draw_geography_rect( + rotation, + length_px, + width_px, + color, + value, + ) scale_bar_box = AuxTransformBox(ax.transData) - scale_bar_box.add_artist(scale_rect) + for rect in scale_rects: + scale_bar_box.add_artist(rect) # Create scale text if scale_loc != "none": From 8c3ecdb730b0bc7ccba4f0eef81d2ec5ddc85181 Mon Sep 17 00:00:00 2001 From: "o.pyhov" Date: Sun, 13 Oct 2024 02:28:54 +0500 Subject: [PATCH 04/10] Implemented geography style for vertical rotation --- matplotlib_scalebar/scalebar.py | 50 ++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/matplotlib_scalebar/scalebar.py b/matplotlib_scalebar/scalebar.py index de6ec8e..ef620bf 100644 --- a/matplotlib_scalebar/scalebar.py +++ b/matplotlib_scalebar/scalebar.py @@ -394,8 +394,7 @@ def _calculate_exact_length(self, value, units): newvalue = self.dimension.convert(value, units, self.units) return newvalue / self.dx - def draw_solid_rect(self, rotation, length_px, width_px, color): - # Create scale bar + def _draw_solid_rect(self, rotation, length_px, width_px, color): if rotation == "horizontal": rec = Rectangle( (0, 0), @@ -416,7 +415,7 @@ def draw_solid_rect(self, rotation, length_px, width_px, color): ) return [rec] - def draw_geography_rect( + def _draw_geography_rect( self, rotation, length_px, @@ -431,30 +430,41 @@ def calc_best_step(length): step = step / 2 return step + step = calc_best_step(value) + step_px = step * length_px / value + def invert_color(color_name): rgb = to_rgba(color_name) return (1 - rgb[0], 1 - rgb[1], 1 - rgb[2]) - step = calc_best_step(value) - step_px = step * length_px / value - second_color = invert_color(color) + current_color = color + inverted_color = invert_color(current_color) filled_px = 0 rectangles = [] - current_color = color while filled_px < length_px: - rec_step_px = step_px if filled_px + step_px <= length_px else length_px - filled_px - rectangles.append( - Rectangle( - (filled_px, 0), - rec_step_px, - width_px, - fill=True, - facecolor=current_color, - edgecolor=color - ) + if filled_px + step_px <= length_px: + rec_step_px = step_px + else: + rec_step_px = length_px - filled_px + if rotation == "horizontal": + rec_xy = (filled_px, 0) + rec_width = rec_step_px + rec_height = width_px + else: + rec_xy = (0, filled_px) + rec_width = width_px + rec_height = rec_step_px + rectangle = Rectangle( + rec_xy, + rec_width, + rec_height, + fill=True, + facecolor=current_color, + edgecolor=color ) - current_color = second_color if current_color == color else color + rectangles.append(rectangle) + current_color, inverted_color = inverted_color, current_color filled_px += rec_step_px return rectangles @@ -534,9 +544,9 @@ def _get_value(attr, default): width_px = abs(ylim[1] - ylim[0]) * width_fraction if not scale_style or scale_style == "solid": - scale_rects = self.draw_solid_rect(rotation, length_px, width_px, color) + scale_rects = self._draw_solid_rect(rotation, length_px, width_px, color) elif scale_style == "geography": - scale_rects = self.draw_geography_rect( + scale_rects = self._draw_geography_rect( rotation, length_px, width_px, From cc223e94e4a0aadf18c041a62052c76eb3355e43 Mon Sep 17 00:00:00 2001 From: "o.pyhov" Date: Sun, 13 Oct 2024 02:35:44 +0500 Subject: [PATCH 05/10] Renamed default style from 'solid' to 'simple'. --- matplotlib_scalebar/scalebar.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/matplotlib_scalebar/scalebar.py b/matplotlib_scalebar/scalebar.py index ef620bf..294a3cc 100644 --- a/matplotlib_scalebar/scalebar.py +++ b/matplotlib_scalebar/scalebar.py @@ -89,7 +89,7 @@ _VALID_ROTATIONS = ["horizontal", "vertical"] _validate_rotation = ValidateInStrings("rotation", _VALID_ROTATIONS, ignorecase=True) -_VALID_SCALE_STYLES = ["solid", "geography"] +_VALID_SCALE_STYLES = ["simple", "geography"] _validate_scale_style = ValidateInStrings("scale_style", _VALID_SCALE_STYLES, ignorecase=True) @@ -114,7 +114,7 @@ def _validate_legend_loc(loc): "scalebar.scale_loc": ["bottom", _validate_scale_loc], "scalebar.label_loc": ["top", _validate_label_loc], "scalebar.rotation": ["horizontal", _validate_rotation], - "scalebar.scale_style": ["solid", _validate_scale_style], + "scalebar.scale_style": ["simple", _validate_scale_style], } ) @@ -285,7 +285,7 @@ def __init__( :type label_loc: :class:`str` :arg scale_style: style of box - (default: rcParams['scalebar.scale_style'] or ``solid``) + (default: rcParams['scalebar.scale_style'] or ``simple``) :type scale_style: :class:`str` :arg font_properties: font properties of the label text, specified @@ -394,7 +394,7 @@ def _calculate_exact_length(self, value, units): newvalue = self.dimension.convert(value, units, self.units) return newvalue / self.dx - def _draw_solid_rect(self, rotation, length_px, width_px, color): + def _draw_simple_rect(self, rotation, length_px, width_px, color): if rotation == "horizontal": rec = Rectangle( (0, 0), @@ -509,7 +509,7 @@ def _get_value(attr, default): box_alpha = _get_value("box_alpha", 1.0) scale_loc = _get_value("scale_loc", "bottom").lower() label_loc = _get_value("label_loc", "top").lower() - scale_style = _get_value("scale_style", "solid") + scale_style = _get_value("scale_style", "simple") font_properties = self.font_properties fixed_value = self.fixed_value fixed_units = self.fixed_units or self.units @@ -543,8 +543,8 @@ def _get_value(attr, default): width_px = abs(ylim[1] - ylim[0]) * width_fraction - if not scale_style or scale_style == "solid": - scale_rects = self._draw_solid_rect(rotation, length_px, width_px, color) + if not scale_style or scale_style == "simple": + scale_rects = self._draw_simple_rect(rotation, length_px, width_px, color) elif scale_style == "geography": scale_rects = self._draw_geography_rect( rotation, From dc324d800d859f02ecaccfa56bcb96bfd8a5f311 Mon Sep 17 00:00:00 2001 From: "o.pyhov" Date: Sun, 13 Oct 2024 02:37:15 +0500 Subject: [PATCH 06/10] Renamed style property from 'scale_style' to 'bar_style'. --- matplotlib_scalebar/scalebar.py | 36 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/matplotlib_scalebar/scalebar.py b/matplotlib_scalebar/scalebar.py index 294a3cc..7648cc9 100644 --- a/matplotlib_scalebar/scalebar.py +++ b/matplotlib_scalebar/scalebar.py @@ -23,7 +23,7 @@ - scalebar.box_alpha - scalebar.scale_loc - scalebar.label_loc - - scalebar.scale_style + - scalebar.bar_style See the class documentation (:class:`.Scalebar`) for a description of the parameters. @@ -90,7 +90,7 @@ _validate_rotation = ValidateInStrings("rotation", _VALID_ROTATIONS, ignorecase=True) _VALID_SCALE_STYLES = ["simple", "geography"] -_validate_scale_style = ValidateInStrings("scale_style", _VALID_SCALE_STYLES, ignorecase=True) +_validate_bar_style = ValidateInStrings("bar_style", _VALID_SCALE_STYLES, ignorecase=True) def _validate_legend_loc(loc): @@ -114,7 +114,7 @@ def _validate_legend_loc(loc): "scalebar.scale_loc": ["bottom", _validate_scale_loc], "scalebar.label_loc": ["top", _validate_label_loc], "scalebar.rotation": ["horizontal", _validate_rotation], - "scalebar.scale_style": ["simple", _validate_scale_style], + "scalebar.bar_style": ["simple", _validate_bar_style], } ) @@ -183,7 +183,7 @@ def __init__( box_alpha=None, scale_loc=None, label_loc=None, - scale_style=None, + bar_style=None, font_properties=None, label_formatter=None, scale_formatter=None, @@ -284,9 +284,9 @@ def __init__( If ``none`` the label is not shown. :type label_loc: :class:`str` - :arg scale_style: style of box - (default: rcParams['scalebar.scale_style'] or ``simple``) - :type scale_style: :class:`str` + :arg bar_style: style of box + (default: rcParams['scalebar.bar_style'] or ``simple``) + :type bar_style: :class:`str` :arg font_properties: font properties of the label text, specified either as dict or `fontconfig `_ @@ -361,7 +361,7 @@ def __init__( self.box_alpha = box_alpha self.scale_loc = scale_loc self.label_loc = label_loc - self.scale_style = scale_style + self.bar_style = bar_style self.scale_formatter = scale_formatter self.font_properties = font_properties self.fixed_value = fixed_value @@ -509,7 +509,7 @@ def _get_value(attr, default): box_alpha = _get_value("box_alpha", 1.0) scale_loc = _get_value("scale_loc", "bottom").lower() label_loc = _get_value("label_loc", "top").lower() - scale_style = _get_value("scale_style", "simple") + bar_style = _get_value("bar_style", "simple") font_properties = self.font_properties fixed_value = self.fixed_value fixed_units = self.fixed_units or self.units @@ -543,9 +543,9 @@ def _get_value(attr, default): width_px = abs(ylim[1] - ylim[0]) * width_fraction - if not scale_style or scale_style == "simple": + if not bar_style or bar_style == "simple": scale_rects = self._draw_simple_rect(rotation, length_px, width_px, color) - elif scale_style == "geography": + elif bar_style == "geography": scale_rects = self._draw_geography_rect( rotation, length_px, @@ -839,18 +839,18 @@ def set_scale_formatter(self, scale_formatter): scale_formatter = property(get_scale_formatter, set_scale_formatter) - def get_scale_style(self): - return self._scale_style + def get_bar_style(self): + return self._bar_style - def set_scale_style(self, scale_style): - if scale_style is not None and scale_style not in _VALID_SCALE_STYLES: + def set_bar_style(self, bar_style): + if bar_style is not None and bar_style not in _VALID_SCALE_STYLES: raise ValueError( - f"Unknown scale_style: {scale_style}. " + f"Unknown bar_style: {bar_style}. " f"Valid locations: {', '.join(_VALID_SCALE_STYLES)}" ) - self._scale_style = scale_style + self._bar_style = bar_style - scale_style = property(get_scale_style, set_scale_style) + bar_style = property(get_bar_style, set_bar_style) def get_label_formatter(self): warnings.warn( From d773a71c426cd31c5aab4cd41407d02462a8b9cc Mon Sep 17 00:00:00 2001 From: "o.pyhov" Date: Sun, 13 Oct 2024 02:50:43 +0500 Subject: [PATCH 07/10] Added tests for bar_style option. --- matplotlib_scalebar/test_scalebar.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/matplotlib_scalebar/test_scalebar.py b/matplotlib_scalebar/test_scalebar.py index 0abb906..40538c0 100644 --- a/matplotlib_scalebar/test_scalebar.py +++ b/matplotlib_scalebar/test_scalebar.py @@ -34,6 +34,7 @@ def scalebar(): yield scalebar plt.draw() + plt.close() def test_mpl_rcParams_update(): @@ -55,6 +56,7 @@ def test_mpl_rcParams_update(): "scalebar.scale_loc": "bottom", "scalebar.label_loc": "top", "scalebar.rotation": "horizontal", + "scalebar.bar_style": "simple", } matplotlib.rcParams.update(params) @@ -327,3 +329,13 @@ def test_bbox_transform(scalebar): scalebar.bbox_transform = scalebar.axes.transAxes assert scalebar.get_bbox_transform() == scalebar.axes.transAxes assert scalebar.bbox_transform == scalebar.axes.transAxes + + +@pytest.mark.parametrize("bar_style", ["simple", "geography"]) +def test_bar_style(scalebar, bar_style): + assert scalebar.get_bar_style() is None + assert scalebar.bar_style is None + + scalebar.set_bar_style(bar_style) + assert scalebar.get_bar_style() == bar_style + assert scalebar.bar_style == bar_style From c83dd61411e63afea69bbe39d82d3b2491ef33e4 Mon Sep 17 00:00:00 2001 From: "o.pyhov" Date: Sun, 13 Oct 2024 04:06:22 +0500 Subject: [PATCH 08/10] Do not invert color, use white. --- matplotlib_scalebar/scalebar.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/matplotlib_scalebar/scalebar.py b/matplotlib_scalebar/scalebar.py index 7648cc9..9c2ebfb 100644 --- a/matplotlib_scalebar/scalebar.py +++ b/matplotlib_scalebar/scalebar.py @@ -433,12 +433,8 @@ def calc_best_step(length): step = calc_best_step(value) step_px = step * length_px / value - def invert_color(color_name): - rgb = to_rgba(color_name) - return (1 - rgb[0], 1 - rgb[1], 1 - rgb[2]) - current_color = color - inverted_color = invert_color(current_color) + second_color = "white" filled_px = 0 rectangles = [] @@ -464,7 +460,7 @@ def invert_color(color_name): edgecolor=color ) rectangles.append(rectangle) - current_color, inverted_color = inverted_color, current_color + current_color, second_color = second_color, current_color filled_px += rec_step_px return rectangles From 0a74df01afd162a7ec5f9381bda62d86830fe0c1 Mon Sep 17 00:00:00 2001 From: "o.pyhov" Date: Sun, 13 Oct 2024 04:13:11 +0500 Subject: [PATCH 09/10] Added example of geography style to doc/. --- doc/bar_style_geography.png | Bin 0 -> 51153 bytes doc/bar_style_geography.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 doc/bar_style_geography.png create mode 100644 doc/bar_style_geography.py diff --git a/doc/bar_style_geography.png b/doc/bar_style_geography.png new file mode 100644 index 0000000000000000000000000000000000000000..d7c03a6ffe433d2828bf1624f209224f73f5f6d9 GIT binary patch literal 51153 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 SJTL4H{3j=^EL9=#D(HVRgEbuh literal 0 HcmV?d00001 diff --git a/doc/bar_style_geography.py b/doc/bar_style_geography.py new file mode 100644 index 0000000..5ac9338 --- /dev/null +++ b/doc/bar_style_geography.py @@ -0,0 +1,34 @@ +import matplotlib.pyplot as plt +from matplotlib_scalebar.scalebar import ScaleBar +from osmnx import features_from_place +from geopandas import GeoSeries +from shapely import Point + +fig, ax = plt.subplots() +ax.xaxis.set_visible(False) +ax.yaxis.set_visible(False) +ax.set_facecolor("ivory") +ax.set_xlim(58.12, 58.20) +ax.set_ylim(54.90, 54.95) + +place = "Ust-Katav" +water_gdf = features_from_place(place, tags={"natural": "water"}) +forest_gdf = features_from_place(place, {"natural": ["wood", "tree", "tree_row"]}) +landuse_gdf = features_from_place(place, tags={"landuse": True}) +highway_gdf = features_from_place(place, tags={"highway": ["secondary", "tertiary"]}) + +forest_gdf.plot(ax=ax, facecolor="palegreen") +landuse_gdf.plot(ax=ax, facecolor="lightgray", edgecolor="gray") +water_gdf.plot(ax=ax, facecolor="lightskyblue", edgecolor="deepskyblue") +highway_gdf.plot(ax=ax, color="palegoldenrod", linewidth=3) + +points = GeoSeries([Point(58.12, 54.90), Point(59.12, 54.90)], crs=4326).to_crs(32619) + +scalebar = ScaleBar( + dx=points[0].distance(points[1]), + bar_style="geography", + length_fraction=1, + width_fraction=0.03, +) +ax.add_artist(scalebar) +fig.savefig("bar_style_geography.png", dpi=60, bbox_inches="tight") From 4959f7fca2dd19ed798ad38d3b936dd713d9672d Mon Sep 17 00:00:00 2001 From: czertyaka Date: Sat, 4 Oct 2025 20:00:24 +0500 Subject: [PATCH 10/10] Fix exception message --- matplotlib_scalebar/scalebar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matplotlib_scalebar/scalebar.py b/matplotlib_scalebar/scalebar.py index 1953331..4e7b973 100644 --- a/matplotlib_scalebar/scalebar.py +++ b/matplotlib_scalebar/scalebar.py @@ -879,7 +879,7 @@ def set_bar_style(self, bar_style): if bar_style is not None and bar_style not in _VALID_SCALE_STYLES: raise ValueError( f"Unknown bar_style: {bar_style}. " - f"Valid locations: {', '.join(_VALID_SCALE_STYLES)}" + f"Valid bar styles: {', '.join(_VALID_SCALE_STYLES)}" ) self._bar_style = bar_style