-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Too much white space around graphs in 3d projection #19519
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
Comments
Hi @Pepe78 that sounds annoying indeed. However, I think that this can likely be resolved with the existing tools in matplotlib. Can you please post about this (with a picture of the output and a description of what you'd expect) on https://discourse.matplotlib.org/ which is the best place for getting help with matplotlib. |
Done (reported at https://discourse.matplotlib.org/). As far as "resolved with the existing tools in matplotlib", it would be nice to have by default less amount of blank space as it is done when not doing 3d projections (2d graphs). Thanks! |
I'm not sure why there is such a large margin around axes3d plots. I have a sneaking suspicion that the margin was developed outside the subplot paradigm, which also have margins, and now we have two sets of margins. Definitely when you add an axes directly via |
This was great advice I got on discourse: fig = plt.figure(figsize=(20,15), constrained_layout=True) Left and right margins were minimal when saved like that (and top and bottom seem also smaller). |
I'll actually re-open, because to me, at least, there is still a mystery about why the margins are so much larger than other axes. |
That makes sense - as I said before, it would be nice to have less margins on sides by default. When doing 2d plots, this actually really works nicely by default. |
Yes, the original Axes3D didn't work within the subplot() framework. And subplots leave extra room for the static axes labels, meanwhile, Axes3D needed to account for extra space for its axes labels within the axes plotting area. Originally, this was fine because you didn't make Axes3D objects using subplots, so you didn't get allocated extra margins for axes labels. When it became possible to specify I never did figure out a good solution for this that wouldn't act counter-intuitively. Perhaps Axes3D needs to be reworked such that it can interpret and express the margin parameters itself rather than letting it be handled by 2D-based assumptions? |
Is there a current workaround for this ? I am having some problems with a figure similar to this situation: import matplotlib.pyplot as plt
import numpy as np
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
fig, ax = plt.subplots(1, 1, figsize=(10, 5), subplot_kw=dict(projection="3d"))
plt.subplots_adjust(0, 0, 1, 1, 0, 0)
surf = ax.plot_surface(X, Y, Z, linewidth=0, antialiased=False)
ax.view_init(elev=20, azim=-45, roll=0)
ax.set_box_aspect([5, 1, 1]) # Aspect ratio
ax.set_aspect("auto")
plt.show() Not that I do not want to use the bbox_inches='tight' when saving the plot, as the figure is already prepared at the right size to be inserted in a paper. |
Yes, the workaround is stated above - add Axes3D manually. |
Could you give a brief example of this? Simply doing
does not show any ax on the figure. |
OK, my mistake. I guess I don't know how you can fix this. Maybe @scottshambaugh has some insight. The overall issue is that you set the box_aspect. I guess the algorithm is conservatice about guessing which direction to shrink based on the current view. |
…at was going on here I tried to figure this out and was kinda getting there but then I realised that because of the 3d axes being generally different than 2d axes and apparently them interacting strangely with subplots() there was a LOT of white space vertically in my subplot grid which is apparently not trivial to get rid of. see here for a discussion: matplotlib/matplotlib#19519
My current workaround is to play with the ax position If for some reason you are using this in a figure, this ax will overlap the other ones, so you might need to hide the background: if in this figure you are using
to fix axis positions from constrained layout, and then disable it to only change the ax position of you 3d figure. |
@cgadal is the |
Yes, it is the import matplotlib.pyplot as plt
import numpy as np
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
fig = plt.figure(figsize=(10, 5), layout="constrained")
ax = fig.add_subplot(111, projection="3d")
surf = ax.plot_surface(X, Y, Z, linewidth=0, antialiased=False)
ax.view_init(elev=20, azim=-45, roll=0)
ax.set_box_aspect([5, 1, 1]) # Aspect ratio
# fig.canvas.draw()
# fig.set_layout_engine("none")
# ax.set_position([-0.75, -0.75, 2.5, 2.5])
# ax.set_facecolor("none")
plt.savefig("Fig_2.png")
plt.show() gives: Uncommenting the commented lines gives: The two first numbers in |
Thank you for the detailed response, it works for my use case as well. I was hoping that I would be able to only change the width and keep the height as it is, but I guess it kind of works as a zoom workaround on the figure level. |
There are two issues being talked about here:
I took a stab at fixing (2) today but my approach wasn't the right one - I don't think that messing with the |
When using 3d projection:
fig = plt.figure(figsize=(20,15))
ax = fig.gca(projection='3d')
and save the figure into png file, there is way too much white space from left right top and bottom, so when I want to add this graph into latex and use it in publication, I have to do post-processing of the image and remove unnecessary amount of blank space.
The text was updated successfully, but these errors were encountered: