Skip to content

Commit

Permalink
Update scalebar.py (#40)
Browse files Browse the repository at this point in the history
* Update scalebar.py

Formalizes the changes suggested by altanir84 in #39 to add support for bbox_to_anchor
Additionally implements get_window_extent

* Update scalebar.py

* Update scalebar.py

* Update scalebar.py

* Apply linter

* Fix use of bbox and add example

* Add doc in README. Add unit test

* Add contributor

---------

Co-authored-by: Philippe Pinard <philippe.pinard@gmail.com>
  • Loading branch information
ilopata1 and ppinard authored Apr 2, 2023
1 parent 4e4dfd0 commit 2c57173
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 4 deletions.
46 changes: 44 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ scalebar = ScaleBar(
fixed_units=None,
animated=False,
rotation=None,
bbox_to_anchor=None,
bbox_transform=None,
)
```

Expand Down Expand Up @@ -333,12 +335,50 @@ ax.add_artist(scalebar)

![rotation](doc/argument_rotation.png)

### bbox_to_anchor and bbox_transform

Use a different bounding box than the plot axes to anchor the scale bar.
The *bbox_transform* defines the transform applied to the *bbox_to_anchor* value.
Note that the *location* will influence the position of the scale bar relative to the anchor (see example below).
Default: `None`, the plot axes bounding box is used.

```python
fig, ax = plt.subplots()

scalebar = ScaleBar(
1,
"cm",
length_fraction=0.25,
bbox_to_anchor=(0.5, 0.5),
bbox_transform=ax.transAxes,
location="lower left",
label="lower left",
box_color="0.8",
)
ax.add_artist(scalebar)

scalebar = ScaleBar(
1,
"cm",
length_fraction=0.25,
bbox_to_anchor=(0.5, 0.5),
bbox_transform=ax.transAxes,
location="upper right",
label="upper right",
box_color="0.8",
)
ax.add_artist(scalebar)
```

![rotation](doc/argument_bbox_to_anchor.png)

## Release notes

### Dev

* Update tooling ([#53][i53])
* Add example gallery ([#50][i50])
* Add *bbox_anchor* and *bbox_transform* ([#40](i40))

### 0.8.1

Expand Down Expand Up @@ -422,13 +462,14 @@ ax.add_artist(scalebar)
[@anntzer](https://github.com/anntzer),
[@bugalo](https://github.com/bugalo),
[@musicinmybrain](https://github.com/musicinmybrain),
[@kolibril13](https://github.com/kolibril13)
[@kolibril13](https://github.com/kolibril13),
[@ilopata1](https://github.com/ilopata1)

## License

License under the BSD License, compatible with matplotlib.

Copyright (c) 2015-2022 Philippe Pinard
Copyright (c) 2015-2023 Philippe Pinard

[i9]: https://github.com/ppinard/matplotlib-scalebar/issues/9
[i11]: https://github.com/ppinard/matplotlib-scalebar/issues/11
Expand All @@ -448,6 +489,7 @@ Copyright (c) 2015-2022 Philippe Pinard
[i35]: https://github.com/ppinard/matplotlib-scalebar/issues/35
[i36]: https://github.com/ppinard/matplotlib-scalebar/issues/36
[i41]: https://github.com/ppinard/matplotlib-scalebar/issues/41
[i40]: https://github.com/ppinard/matplotlib-scalebar/pull/40
[i44]: https://github.com/ppinard/matplotlib-scalebar/pull/44
[i47]: https://github.com/ppinard/matplotlib-scalebar/pull/47
[i48]: https://github.com/ppinard/matplotlib-scalebar/pull/48
Expand Down
Binary file added doc/argument_bbox_to_anchor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions doc/argument_bbox_to_anchor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib_scalebar.scalebar import ScaleBar

fig, ax = plt.subplots()

scalebar = ScaleBar(
1,
"cm",
length_fraction=0.25,
bbox_to_anchor=(0.5, 0.5),
bbox_transform=ax.transAxes,
location="lower left",
label="lower left",
box_color="0.8",
)
ax.add_artist(scalebar)

scalebar = ScaleBar(
1,
"cm",
length_fraction=0.25,
bbox_to_anchor=(0.5, 0.5),
bbox_transform=ax.transAxes,
location="upper right",
label="upper right",
box_color="0.8",
)
ax.add_artist(scalebar)

outdir = Path(__file__).parent.resolve()
fig.savefig(outdir / "argument_bbox_to_anchor.png", dpi=60, bbox_inches="tight")
2 changes: 1 addition & 1 deletion doc/splashscreen.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

ax.imshow(im, "gray")

# According to Wikipedia,
# According to Wikipedia,
# "the bean shaped grain in the bottom left corner is about 50 μm long."
scalebar = ScaleBar(
50 / 144, "um", location="lower right", width_fraction=0.02, border_pad=1, pad=0.5
Expand Down
35 changes: 34 additions & 1 deletion matplotlib_scalebar/scalebar.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ def __init__(
fixed_units=None,
animated=False,
rotation=None,
bbox_to_anchor=None,
bbox_transform=None,
):
"""
Creates a new scale bar.
Expand Down Expand Up @@ -299,6 +301,13 @@ def __init__(
:arg rotation: either ``horizontal`` or ``vertical``
(default: rcParams['scalebar.rotation'] or ``horizontal``)
:type rotation: :class:`str`
:arg bbox_to_anchor: box that is used to position the scalebar
in conjunction with location. If ``None`` the figure bbox is used.
:type bbox_to_anchor: :class:`BboxBase`, `2-tuple`, or `4-tuple` of floats
:arg bbox_transform: transform for the bounding box
:type bbox_transform: :class:`matplotlib.transforms.Transform`
"""
Artist.__init__(self)

Expand Down Expand Up @@ -346,6 +355,8 @@ def __init__(
self.fixed_units = fixed_units
self.set_animated(animated)
self.rotation = rotation
self.bbox_to_anchor = bbox_to_anchor
self.bbox_transform = bbox_transform

def _calculate_best_length(self, length_px):
dx = self.dx
Expand Down Expand Up @@ -509,7 +520,13 @@ def _get_value(attr, default):
child = scale_box

box = AnchoredOffsetbox(
loc=location, pad=pad, borderpad=border_pad, child=child, frameon=frameon
loc=location,
pad=pad,
child=child,
borderpad=border_pad,
frameon=frameon,
bbox_to_anchor=self.bbox_to_anchor,
bbox_transform=self.bbox_transform,
)

box.axes = ax
Expand Down Expand Up @@ -788,3 +805,19 @@ def set_rotation(self, rotation):
self._rotation = rotation

rotation = property(get_rotation, set_rotation)

def get_bbox_to_anchor(self):
return self._bbox_to_anchor

def set_bbox_to_anchor(self, bbox_to_anchor):
self._bbox_to_anchor = bbox_to_anchor

bbox_to_anchor = property(get_bbox_to_anchor, set_bbox_to_anchor)

def get_bbox_transform(self):
return self._bbox_transform

def set_bbox_transform(self, bbox_transform):
self._bbox_transform = bbox_transform

bbox_transform = property(get_bbox_transform, set_bbox_transform)
19 changes: 19 additions & 0 deletions matplotlib_scalebar/test_scalebar.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

matplotlib.use("agg")


@pytest.fixture
def scalebar():
fig = plt.figure()
Expand Down Expand Up @@ -308,3 +309,21 @@ def test_rotation(scalebar, rotation):

with pytest.raises(ValueError):
scalebar.set_rotation("h")


def test_bbox_to_anchor(scalebar):
assert scalebar.get_bbox_to_anchor() is None
assert scalebar.bbox_to_anchor is None

scalebar.bbox_to_anchor = (0.5, 0.5)
assert scalebar.get_bbox_to_anchor() == (0.5, 0.5)
assert scalebar.bbox_to_anchor == (0.5, 0.5)


def test_bbox_transform(scalebar):
assert scalebar.get_bbox_transform() is None
assert scalebar.bbox_transform is None

scalebar.bbox_transform = scalebar.axes.transAxes
assert scalebar.get_bbox_transform() == scalebar.axes.transAxes
assert scalebar.bbox_transform == scalebar.axes.transAxes

0 comments on commit 2c57173

Please sign in to comment.