Reputation: 53
I have tried to find a way to display the coordinate-axes of a 3D-space at a different location than matplotlib does by default.
To show the desired situation I have provided two figures in which I draw the eight corners of a cube.
Figure 1: matplotlib-default of drawing coordinate axes
Figure 1 is the default presentation of the coordinate axes of matplotlib. The coordinate axes are drawn "at the ends of spaces.
Figure 2: desired place when drawing coordinate axes
The presentation in Figure 2 shows the coordinate axes originating from one common point. This is the desired presentation.
The question is now: "How can I achieve the desired situation?"
I have looked around and could not find an answer to this question. I think it may be a simple setting that is not so easy find, an therefore I have also supplied the code that generates the "matplotlib default presentation" (see below).
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def plot_3Dcube():
"""Plots a 3D cube in a 3D-window
"""
#--------------------------------------
# PROCESS ARGUMENTS AND LOCAL VARIABLES
#--------------------------------------
mycube = cube() # The cube to be plotted
#---------------
# Setup the plot
#---------------
fig = plt.figure()
ax = fig.add_subplot(111,projection="3d")
#---------------------------------------------
# Format the point-data and add it to the plot
#---------------------------------------------
colour = (1.0, 0, 0, 1) # RGB, alpha
mrkr = '^'
s = 50
print (mycube)
ax.scatter(mycube[:,0],mycube[:,1],mycube[:,2],
c = colour,
marker = mrkr
)
ptnr=0
for row in mycube:
ptnr += 1
ax.text(row[0],row[1],row[2],str(ptnr),
size = 8,
color = (0,0,0)
)
#----------------
# Format the plot
#----------------
ax.set_xlabel('X as')
ax.set_ylabel('Y as')
ax.set_zlabel('Z as')
#--------------
# SHOW THE PLOT
#--------------
ax.view_init(15,30)
plt.show()
#=-=-=-=-=-=-=-=-=-=-=-
# RETURN FROM FUNCTION
#=-=-=-=-=-=-=-=-=-=-=-
return None
#</plot_3dCube()>
def cube():
"""Returns the eight points of a cube in a numpy-array.
"""
c = np.array([[5.0, 0.0, 5.0], # Ptnr 1, Front UpperLeft
[5.0, 5.0, 5.0], # Ptnr 2, Front Upper Right
[5.0, 5.0, 0.0], # Ptnr 3, Front Lower Right
[5.0, 0.0, 0.0], # Ptnr 4, Front Lower Left
[0.0, 0.0, 5.0], # Ptnr 5, Back, Upper Right
[0.0, 5.0, 5.0], # Ptnr 6, Back, Upper Left
[0.0, 5.0, 0.0], # Ptnr 7, Back, Lower Left
[0.0, 0.0, 0.0], # Ptnr 8, Back, Lower Right
])
return c
#</cube()>
#==================================================================
# TEST area
#==================================================================
def main():
print ("Entering Main()\n")
plot_3Dcube()
#</main()>
if __name__ == "__main__":
main()
Thanks in advance for your help.
Upvotes: 1
Views: 417
Reputation: 12618
There seems to be at leas a couple of might-be-duplicates out there but it is not crystal clear to me whether they are asking exactly the same and none of the answers seem to address your specific issue.
I was able to come up with a solution based on another answer. To be fair I don't really understand what the numbers actually mean, I got it (more or less) working by trial and error.
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.xaxis._axinfo['juggled'] = 0, 0, 0
ax.yaxis._axinfo['juggled'] = 1, 1, 1
ax.zaxis._axinfo['juggled'] = 2, 2, 2
If you are doing this in some kind of interactive environment call plt.draw()
to see the changes.
There are still some issues for you to solve. The orientation of the Y axis might not be what you want and the readability of the labels is less than ideal. Hopefully you will find your way around these.
Be aware that you are using an attribute that is not intended to be part of the public API and setting a key called juggled
. Expect this to break at any moment.
Upvotes: 2