BUG: Return null Bbox when there is no intersection for bar_label center. by stefmolin · Pull Request #25681 · matplotlib/matplotlib · GitHub
Skip to content

BUG: Return null Bbox when there is no intersection for bar_label center. - #25681

Merged
ksunden merged 3 commits into
matplotlib:mainfrom
stefmolin:null-bbox
Apr 17, 2023
Merged

BUG: Return null Bbox when there is no intersection for bar_label center.#25681
ksunden merged 3 commits into
matplotlib:mainfrom
stefmolin:null-bbox

Conversation

@stefmolin

Copy link
Copy Markdown
Contributor

PR Summary

Addresses #25625

When using bar_label(label_type='center') and axis limits that cut off some of the bars, an exception was raised because the Bbox intersection was None. This PR makes sure the plot can still be created.

PR Checklist

Documentation and Tests

  • Has pytest style unit tests (and pytest passes)
  • [N/A] Documentation is sphinx and numpydoc compliant (the docs should build without error).
  • [N/A] New plotting related features are documented with examples.

Release Notes

  • [N/A] New features are marked with a .. versionadded:: directive in the docstring and documented in doc/users/next_whats_new/
  • [N/A] API changes are marked with a .. versionchanged:: directive in the docstring and documented in doc/api/next_api_changes/
  • [N/A] Release notes conform with instructions in next_whats_new/README.rst or next_api_changes/README.rst

@ksunden

ksunden commented Apr 14, 2023

Copy link
Copy Markdown
Member

@timhoffm

timhoffm commented Apr 14, 2023

Copy link
Copy Markdown
Member

@ksunden - Your proposal is quite orthogonal to the above issue. (It would open up another type of fix, but only after a deprecation period)

  1. bool-evaluating a null-object to false totally makes sense. Slight unclarity should the half-null boxes with one finite dimension also be false or not? I have no clear opinion on that, which is likely because I don't know in which contexts they appear.

  2. Returning null boxes instead of None.

Since Bbox.null() already defines the null-object concept, we could use it. (I'm generally very torn on the use of null-objects in Python). However, we have a significant compatibility barrier:

https://matplotlib.org/stable/api/transformations.html#matplotlib.transforms.BboxBase.intersection

Return the intersection of bbox1 and bbox2 if they intersect, or None if they don't.

is public API and very clear about the return value. Any user will canonically check intersection() is not None and not not intersection(). If we want to go there we need a regular deprecation cycle (and it's nasty because we cannot runtime-warn on it).

I've no clear how widespread this is used, but would imagine that there's a bit of user code out there, that would be affected.

Additional question: How is consistency across other functions returning bboxes. Do we have other cases that can return invalid boxes? If so, do they return null() or None?

Overall:

  • (1) yes;
  • (2) I'm sceptical on the cost-benefit ratio.

@tacaswell

Copy link
Copy Markdown
Member

I agree with @timhoffm 's analysis and that we should handle the wider issue independently of this PR.

@tacaswell tacaswell added this to the v3.7.2 milestone Apr 14, 2023
@timhoffm

Copy link
Copy Markdown
Member

None of the below is critical, because fixing the RuntimeError is most important. But


When running the code from the test I get a warning log from

_log.warning("posx and posy should be finite values")

This is not helpful for the end user, but I don't know whether we can do something about it. - Does a warning from a deep burried draw() function make sense at all? Maybe we should switch to info or debug.


Edge case: Setting the limit to the bar border still draws the label:

import matplotlib.pyplot as plt

_, ax = plt.subplots()

last = 0
for label, value in zip(['a', 'b', 'c'], [10, 20, 50]):
    bar_container = ax.barh('col', value, label=label, left=last)
    ax.bar_label(bar_container, label_type='center')
    last += value
ax.set_xlim(None, 30)

#plt.savefig(tmp_path / 'test')
plt.show()

grafik

@QuLogic QuLogic left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please rebase to latest main to fix CI.

Comment thread lib/matplotlib/tests/test_axes.py Outdated

@ksunden ksunden left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Fair points, all around, just a thought prompted by this change.

@ksunden
ksunden merged commit 0e7f29e into matplotlib:main Apr 17, 2023
meeseeksmachine pushed a commit to meeseeksmachine/matplotlib that referenced this pull request Apr 17, 2023
oscargus added a commit that referenced this pull request Apr 17, 2023
…681-on-v3.7.x

Backport PR #25681 on branch v3.7.x (BUG: Return null Bbox when there is no intersection for bar_label center.)
@mrgransky

Copy link
Copy Markdown

None of the below is critical, because fixing the RuntimeError is most important. But

When running the code from the test I get a warning log from

This is not helpful for the end user, but I don't know whether we can do something about it. - Does a warning from a deep burried draw() function make sense at all? Maybe we should switch to info or debug.

Edge case: Setting the limit to the bar border still draws the label:

import matplotlib.pyplot as plt

_, ax = plt.subplots()

last = 0
for label, value in zip(['a', 'b', 'c'], [10, 20, 50]):
    bar_container = ax.barh('col', value, label=label, left=last)
    ax.bar_label(bar_container, label_type='center')
    last += value
ax.set_xlim(None, 30)

#plt.savefig(tmp_path / 'test')
plt.show()

grafik

I tried this approach to apply some margin on the right hand side of the figure:
ax.set_xlim(right=ax.get_xlim()[1]+1.0, auto=True)
it fixes the runtime error at least!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants