Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[MNT]: The new default x and ymargin setting is too wasteful #25599

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nikohansen opened this issue Apr 1, 2023 · 9 comments
Closed

[MNT]: The new default x and ymargin setting is too wasteful #25599

nikohansen opened this issue Apr 1, 2023 · 9 comments

Comments

@nikohansen
Copy link

Summary

The current margin setting, 0.05=5%, reserves 19% of the plotting area as additional margin and hence blank (wasted) space. A margin of 0.01=1% reserves/wastes only 4% and would be a better default.

Proposed fix

The default setting should be amended to 0.01 which would add 18.6% usable area.

The amount of wasted space is surprising, given the margin is only 5%. However, we have 4 margins, hence we should expect to waste roughly 4x5% = 20%. More precisely, the plotting area fraction computes to (1 - 2 * 0.05)**2 = 0.81 of the original area.

A margin of 1% is probably what the default margin setting actually intended, as this removes 4% of the usable area (1 - 2 * 0.01)**2 = 0.96.

Changing the margin from 5% to 1% adds 18.6% to the plotting area ((1 - 2 * 0.01)**2 / (1 - 2 * 0.05)**2 = 1.186), or, the other way around, it makes the plot content 18.6% larger without changing the overall plot size.

@jklymak
Copy link
Member

jklymak commented Apr 1, 2023

That margin isn't exactly new, having come in 6 years ago w Matplotlib 2.0. We consider changing defaults a breaking change so would only happen when a lot of defaults were changed at once. You can change your default margins using the matplotlibrc file. https://matplotlib.org/stable/tutorials/introductory/customizing.html. How much whitespace to leave on a plot is completely artistic and not going to be decided by math or consensus, that's why we have style sheets.

@anntzer
Copy link
Contributor

anntzer commented Apr 1, 2023

Agreed that this is basically not going to change due to backcompatibility.

@anntzer anntzer closed this as completed Apr 1, 2023
@nikohansen
Copy link
Author

How much whitespace to leave on a plot is completely artistic

I use plotting as a tool to convey information, in which case there is almost invariably a shortage of space on screens (and on paper) and larger is almost invariably better readable than smaller. That's a question of core functionality, not a question of artistic choice.

@tacaswell
Copy link
Member

I use plotting as a tool to convey information,

As does almost everyone else who uses Matplotlib. The reason we are making plots is to communicate something to other people and, just like writing the prose of a paper, there is an art to making effective plots.

Going to a margin of 0 is problematic (nearly vertical lines at the edges can get lost in the axes frame) and going to huge margins is also problematic so it does follow that there is an optimum margin value between 0 and infinity. However that optimum is going to be domain, context, and possibly data dependent. In some cases (such as yours) the default margin may be too big and in other cases it will be too small. Picking a different value for the default would only change the set of The axes.xmargin and axes.ymargin rcparams are for precisely this situation so you can set margins better suited to your needs (and this discussion is only about the auto-limiting, you can always manually set the limits).

See https://matplotlib.org/stable/users/prev_whats_new/dflt_style_changes.html#auto-limits for some context.

As both Jody and Antony note, this is now a 6yr old default, it is very unlikely we are going to change it due to back-compatibility concerns, and there are multiple ways globally and per-plot override the default behavior.

The only action I see here would be maybe adding an example with a 2x2 grid of 0, 1%, 5%, and 10% margins using rc_context or similar.

@rcomer
Copy link
Member

rcomer commented Apr 2, 2023

I notice that the autoscaling section in the user guide states

The default margin around the data limits is 5%

This should perhaps be updated to indicate that it defaults to the rcParam (which defaults to 5%). Possibly the docstrings of the various margin setting methods could also be updated to state where the default comes from.

@nikohansen
Copy link
Author

Going to a margin of 0 is problematic (nearly vertical lines at the edges can get lost in the axes frame)

Right, prioritizing the frame over plotted data is IMHO another default that was somewhat suboptimally chosen. If frame and data collide, data should have the priority by default because data carries content and the frame is at best beautiful.

and going to huge margins is also problematic so it does follow that there is an optimum margin value between 0 and infinity.

We can reduce the eligible range drastically by just thinking about it: any margin equal or above 0.5=50% is with certainty bad, unless plotting nothing is preferable over plotting anything.

I am a little surprised over the resistance to fathom that blanking on 19% of the area available for content is in the majority of circumstances pretty suboptimal.

Picking a different value for the default would only change the set of The axes.xmargin and axes.ymargin

True, I have opened this issue not because I was not able or willing to change my default settings (I use matplotlib since about 15 years). I stumbled over the problem because other people use the default setting and it is hurting their presentations without that they even realize. To minimize these situations is, I believe, what default settings are for.

@rcomer
Copy link
Member

rcomer commented Apr 3, 2023

blanking on 19% of the area available for content

Note that the margins are set around the data interval. They need to be large enough to accommodate the artists themselves, and are not necessarily blank. For example, if you try scatter with 1% margins, the markers start to disappear behind the axes frame.

import matplotlib.pyplot as plt
import numpy as np

arr = np.random.rand(10)
fig, ax = plt.subplots()

ax.margins(0.01, 0.01)
ax.scatter(range(10), arr)

plt.show()

test

@tacaswell
Copy link
Member

🤦🏻 I messed up the editing in my last post, meant to say:

Picking a different value for the default would only change the set of people for whom the value is non-ideal to a different set of people.

@nikohansen
Copy link
Author

For example, if you try scatter with 1% margins, the markers start to disappear behind the axes frame.

True, it looks like we want 0.02 instead of 0.01 with scatter symbols. Or, putting it more general, the margin should be slightly larger than half of the symbol size of the used symbols. This also means that it can not be the same percentage on all edges, unless the figure is square.

would only change the set of people for whom the value is non-ideal to a different set of people.

That's true for any two default settings.

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

No branches or pull requests

6 participants