1

I'm trying to plot 3D traces of simulated ion movement through a pore using matplotlib and mplot3d, but I'm having an issue with fitting the graph into the generated viewport.

My initial problem was that the axes were not scaled properly, with the z-axis taking up the same amount of space as the x- and y-axes despite being three times the length (apologies for the link, I don't have the reputation to embed yet): poor scaling.

I fixed this using Andrzej Pronobis' answer from this question, however, this leads to another problem -- the graph no longer fits in the viewport: ill-fitting graph.

Increasing the figure size does not help, and zooming in and out just changes the axes, not the size of the graph itself. Does anyone know how to "zoom out" the viewport itself or scale the plot down so it fits in the window? Below is my abbreviated code. Thanks for your help.

# Imports
# (various other stuff...)
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# (load data and extract xyz coordinates)

# Make axes
fig = plt.figure(figsize = (10, 10))
ax = fig.add_subplot(111, projection = "3d")

# Set properties
ax.set_xlim3d([-20.0, 20.0])
ax.set_xlabel("X")
ax.set_ylim3d([-20.0, 20.0])
ax.set_ylabel("Y")
ax.set_zlim3d([-60.0, 60.0])
ax.set_zlabel("Z")

# Properly scale the axes
ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), np.diag([1, 1, 3, 1]))

# Plot data
ax.plot(xs = x, ys = y, zs = z)

# Display results
plt.show()
Umair Khan
  • 13
  • 6

1 Answers1

0

You may use e.g. [1, 1, 3, 1.75]

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure(figsize = (8,8))
ax = fig.add_subplot(111, projection = "3d")

ax.set_xlim3d([-20.0, 20.0])
ax.set_xlabel("X")
ax.set_ylim3d([-20.0, 20.0])
ax.set_ylabel("Y")
ax.set_zlim3d([-60.0, 60.0])
ax.set_zlabel("Z")

# Properly scale the axes
ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), np.diag([1, 1, 3, 1.75]))

plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • Thank you! Just looked through the [documentation](https://matplotlib.org/3.1.1/api/_as_gen/mpl_toolkits.mplot3d.axes3d.Axes3D.html) and it looks like this value encodes for distance of the viewer, in case anyone else is wondering why it works. I never thought to look at this part of the code. – Umair Khan Aug 13 '19 at 23:57