I've noticed, from what I can tell, that matplotlib 3D plots are restricted to a square drawing area. For example, when plotting a surface and zooming in, instead of the surface filling the entire window, it remains confined to a square region fitted inside the window, with blank borders:
I couldn’t find any way to change that behavior nor any mention of this limitation in the documentation or online discussions. Is there any way to change this so that the drawing area can have a non-square aspect ratio and dynamically resize with the window? Any pointers or workarounds would be appreciated.
My simplified code:
import numpy as np
import matplotlib.pyplot as plt
# Generate some sample data
x = np.arange(10)
y = np.arange(15)
X, Y = np.meshgrid(x, y)
Z = np.random.randn(15, 10)
# Create figure and 3D axes
fig = plt.figure(figsize=(8, 6), dpi=100)
ax = fig.add_subplot(111, projection="3d")
# Plot surface
ax.plot_surface(X, Y, Z, cmap="inferno", linewidth=0, antialiased=True)
# Set labels
ax.set_xlabel("Delta")
ax.set_ylabel("Maturity")
ax.set_zlabel("Volatility")
ax.set_title("Volatility Surface")
# Show plot
plt.show()
I've noticed, from what I can tell, that matplotlib 3D plots are restricted to a square drawing area. For example, when plotting a surface and zooming in, instead of the surface filling the entire window, it remains confined to a square region fitted inside the window, with blank borders:
I couldn’t find any way to change that behavior nor any mention of this limitation in the documentation or online discussions. Is there any way to change this so that the drawing area can have a non-square aspect ratio and dynamically resize with the window? Any pointers or workarounds would be appreciated.
My simplified code:
import numpy as np
import matplotlib.pyplot as plt
# Generate some sample data
x = np.arange(10)
y = np.arange(15)
X, Y = np.meshgrid(x, y)
Z = np.random.randn(15, 10)
# Create figure and 3D axes
fig = plt.figure(figsize=(8, 6), dpi=100)
ax = fig.add_subplot(111, projection="3d")
# Plot surface
ax.plot_surface(X, Y, Z, cmap="inferno", linewidth=0, antialiased=True)
# Set labels
ax.set_xlabel("Delta")
ax.set_ylabel("Maturity")
ax.set_zlabel("Volatility")
ax.set_title("Volatility Surface")
# Show plot
plt.show()
Share
Improve this question
edited Mar 20 at 22:01
LoneCodeRanger
asked Mar 20 at 21:54
LoneCodeRangerLoneCodeRanger
5507 silver badges22 bronze badges
1 Answer
Reset to default 1Not sure this is what you're trying to achieve, but you could set a clip-path for the surface to achieve a non-rectangular area after zooming in... e.g:
...
# Plot surface
s = ax.plot_surface(X, Y, Z, cmap="inferno", linewidth=0, antialiased=True)
from matplotlib.patches import Circle
c = Circle((0.5, 0.5), 0.5, transform=ax.transAxes)
s.set_clip_path(c)
...