Simple to solve problem, making issue just to refer to it in the PR.
Bug report
For lines, Axes.get_tightbbox relies on Line2D.get_window_extent, which computes extra padding due to markers as
ms= (self._markersize/72.0*self.figure.dpi) *0.5
but this can cut off half of the marker edge.
This phenomena which is only visible if you have a line that extends outside of a plot, and has markeredgewidth > 1. For simple markers, (like 'S', 'O'), the code should instead read
This seems like a pretty niche use case, and begs the question what I'm doing to make it necessary:
Say you're making a figure for publication, so that the font size, and figure width is fixed. In modern biology, it's not uncommon to be VERY short on figure space, leading to figures with funny sizes, like the following:
As you can see, the markers overlap strongly across plots. I can easily fix this by just spacing the axes myself. But for that I need to know the ax.get_tightbbox, which is currently wrong.
Normally being a little bit off wouldn't be a big deal, but in these figures where the marker edge width is comparable to the figure size, (say >1% of total figure size or so) then being off by a bit can make some of the axes look noticeably misspaced.
I like to think I understand the internals of matplotlib more than the average use, and even when being pretty clever, I simply don't have a way to space the axes nicely without knowing where the bbox's are
Originally I had hoped to just add markeredgewidth/2 padding to the existing bbox calculation code, but since this underestimates the extents of corners, if I'm not careful I can cause my markers to be cut off (which looks V ugly).
I'm sure you already know this, but that would be an overestimate for some markers (e.g. 'o', 's', etc.), where markeredgewidth/2 is the correct amount.
So using the code in my PR would allow the figure boundary to be set "exactly flush" with the markers, instead of leaving annoying whitespace that has to be removed in Illustrator.
But if it is agreed that an overestimate is what we want (even though I already have the code to compute the bbox exactly written), then I can compute what the correct amount to add is (assuming e.g. the miter default limit). I'd guess that it will be a hair larger than +markeredgewidth, because of some sharp corners like the top of marker='d', but you might be right, I'd have to check.
Yes, you would lose a couple of pixels for circles. I think if your figure is so cramped that you even need those (I've played the game of 6 figures x 25 subfigures each too...) then perhaps you can either slightly change the figure design, or even(!) manually set slightly larger margins :)
Yes, you would lose a couple of pixels for circles. I think if your figure is so cramped that you even need those (I've played the game of 6 figures x 25 subfigures each too...) then perhaps you can either slightly change the figure design, or even(!) manually set slightly larger margins :)
I don't disagree with you!! My advisor might though (he really likes the game of (a)-(q) subfigures). I'm still playing the game of trying to convince him that using Python is worth it, which is the impetus for trying to get something mainlined.
At that point the fix is more about matplotlib "feeling professional" (in the sense that it works exactly and correctly as advertised) vs it being a real problem (I can always just trim some extra whitespace in illustrator....or let the margins be a few pixels uneven....
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
Activity
brunobeltran commented on Mar 5, 2020
This seems like a pretty niche use case, and begs the question what I'm doing to make it necessary:
Say you're making a figure for publication, so that the font size, and figure width is fixed. In modern biology, it's not uncommon to be VERY short on figure space, leading to figures with funny sizes, like the following:
As you can see, the markers overlap strongly across plots. I can easily fix this by just spacing the axes myself. But for that I need to know the ax.get_tightbbox, which is currently wrong.
Normally being a little bit off wouldn't be a big deal, but in these figures where the marker edge width is comparable to the figure size, (say >1% of total figure size or so) then being off by a bit can make some of the axes look noticeably misspaced.
I like to think I understand the internals of matplotlib more than the average use, and even when being pretty clever, I simply don't have a way to space the axes nicely without knowing where the bbox's are
brunobeltran commented on Mar 5, 2020
Originally I had hoped to just add markeredgewidth/2 padding to the existing bbox calculation code, but since this underestimates the extents of corners, if I'm not careful I can cause my markers to be cut off (which looks V ugly).
anntzer commented on Mar 5, 2020
What about just doing +markeredgewidth instead?
brunobeltran commented on Mar 5, 2020
I'm sure you already know this, but that would be an overestimate for some markers (e.g. 'o', 's', etc.), where markeredgewidth/2 is the correct amount.
So using the code in my PR would allow the figure boundary to be set "exactly flush" with the markers, instead of leaving annoying whitespace that has to be removed in Illustrator.
But if it is agreed that an overestimate is what we want (even though I already have the code to compute the bbox exactly written), then I can compute what the correct amount to add is (assuming e.g. the miter default limit). I'd guess that it will be a hair larger than +markeredgewidth, because of some sharp corners like the top of marker='d', but you might be right, I'd have to check.
anntzer commented on Mar 5, 2020
Yes, you would lose a couple of pixels for circles. I think if your figure is so cramped that you even need those (I've played the game of 6 figures x 25 subfigures each too...) then perhaps you can either slightly change the figure design, or even(!) manually set slightly larger margins :)
brunobeltran commented on Mar 5, 2020
I don't disagree with you!! My advisor might though (he really likes the game of (a)-(q) subfigures). I'm still playing the game of trying to convince him that using Python is worth it, which is the impetus for trying to get something mainlined.
brunobeltran commented on Mar 5, 2020
At that point the fix is more about matplotlib "feeling professional" (in the sense that it works exactly and correctly as advertised) vs it being a real problem (I can always just trim some extra whitespace in illustrator....or let the margins be a few pixels uneven....
anntzer commented on Mar 6, 2020
I got your point :-) let's keep the discussion on the PR side to avoid splitting it in two places.
github-actions commented on Jul 10, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
anntzer commented on Aug 11, 2023
Let's keep this open, if open to keep track of #17198 (which seems useful in itself).