1

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.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
PeterDev
  • 53
  • 1
  • 4

1 Answers1

2

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.

enter image description here

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.

Stop harming Monica
  • 12,141
  • 1
  • 36
  • 56
  • Thank you. This is exacly the way that I wanted to represent the coordinate axes. I tried it out and it works fine in my code too. The axes are in the expected directions, although I need to play a bit with the axis-label locations indeed, just as you mentioned. Because it is not part of the public API, I will place it in a try-except block. I think I will be safe for the future then. – PeterDev May 12 '18 at 18:17