2

When using matplotlib in jupyter notebook in VS code the Z-label of my 3D plot is cut off. I also used the example code from the official matplotlib documentation:

import matplotlib.pyplot as plt import numpy as np # Fixing random state for reproducibility np.random.seed(19680801) def randrange(n, vmin, vmax): """ Helper function to make an array of random numbers having shape (n, ) with each number distributed Uniform(vmin, vmax). """ return (vmax - vmin)*np.random.rand(n) + vmin fig = plt.figure() ax = fig.add_subplot(projection='3d') n = 100 # For each set of style and range settings, plot n random points in the box # defined by x in [23, 32], y in [0, 100], z in [zlow, zhigh]. for m, zlow, zhigh in [('o', -50, -25), ('^', -30, -5)]: xs = randrange(n, 23, 32) ys = randrange(n, 0, 100) zs = randrange(n, zlow, zhigh) ax.scatter(xs, ys, zs, marker=m) ax.set_xlabel('X Label') ax.set_ylabel('Y Label') ax.set_zlabel('Z Label') plt.show()

This code returns the following image:

Plot with cut off z label

I already tried to change the figure size and ax.dist as suggested in this Answer, both did not resolve the issue. My python version is 3.11.6 and matplotlib 3.8.1.

1 Answer 1

11

The answer you reference works with Matplotlib 3.7.1, which shows the same issue as in your post image. (ax.dist=13 added before plt.show() line doesn't show Z label' cut off.) However, I get a deprecated warning when I use that approach.
That lead me to here that suggests using ax.set_box_aspect() to set zoom. Setting of value one is default according to the documentation.

This addition of ax.set_box_aspect(None, zoom=0.85) worked for Matplotlib 3.7.1:

import matplotlib.pyplot as plt import numpy as np # Fixing random state for reproducibility np.random.seed(19680801) def randrange(n, vmin, vmax): """ Helper function to make an array of random numbers having shape (n, ) with each number distributed Uniform(vmin, vmax). """ return (vmax - vmin)*np.random.rand(n) + vmin fig = plt.figure() ax = fig.add_subplot(projection='3d') n = 100 # For each set of style and range settings, plot n random points in the box # defined by x in [23, 32], y in [0, 100], z in [zlow, zhigh]. for m, zlow, zhigh in [('o', -50, -25), ('^', -30, -5)]: xs = randrange(n, 23, 32) ys = randrange(n, 0, 100) zs = randrange(n, zlow, zhigh) ax.scatter(xs, ys, zs, marker=m) ax.set_xlabel('X Label') ax.set_ylabel('Y Label') ax.set_zlabel('Z Label') #ax.dist = 13 ax.set_box_aspect(None, zoom=0.85) plt.show() 
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you very much, this already helped a lot. Just a minor follow up question: Your solution zooms out, so there is a lot of white on the left side, while the right label is visible but still near the edge. Is there a way to move the entire box left instead of zooming out?
I'm not seeing a lot of white on the left side. Maybe your situation is different. I didn't see the addition of plt.tight_layout() changing anything. I think the space on the right is calculated by what would be necessary if you were to rotate the plot any option of 306 degrees. (As to why it fails on the left now and needs the zoom, I don't know.) I think if you make a 2D plot instead you'll see it if flush on left, like on bottom here.
<continued> As for "Is there a way to move the entire box left instead of zooming out? " , there's notes on centering in Jupyter out there but they may no longer work as the interface of the most current Jupyter is now based on components JupyterLab and some of those old tricks don't work as spelled out. I don't know what version you are working in and so maybe that would help you. You can find what I mean by searching in your browser for 'align matpltolib plot in Jupyter'. There's also stuff about adding padding to margins you can look into since I'm not sure what is your full issue here.
This really helped!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.