How do I crop an Axes3D plot with square aspect ratio?

前端 未结 2 772
生来不讨喜
生来不讨喜 2021-01-07 18:22

Here\'s a barebones example:

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

fig = plt.figure()
f = fig.add_subplot(2, 1, 1, project         


        
相关标签:
2条回答
  • 2021-01-07 18:50

    In order to follow up on my comments and show examples by settting a smaller r and removing subplot margins using subplots_adjust:

     
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    
    fig = plt.figure()
    f = fig.add_subplot(2, 1, 1, projection='3d')
    t = fig.add_subplot(2, 1, 2, projection='3d')
    
    # axes
    for d in {f, t}:
        d.plot([-1, 1], [0, 0], [0, 0], color='k', alpha=0.8, lw=2)
        d.plot([0, 0], [-1, 1], [0, 0], color='k', alpha=0.8, lw=2)
        d.plot([0, 0], [0, 0], [-1, 1], color='k', alpha=0.8, lw=2)
    
    f.dist = t.dist = 5.2   # 10 is default
    
    plt.tight_layout()
    f.set_aspect('equal')
    t.set_aspect('equal')
    
    r = 1
    f.set_xlim3d([-r, r])
    f.set_ylim3d([-r, r])
    f.set_zlim3d([-r, r])
    
    t.set_xlim3d([-r, r])
    t.set_ylim3d([-r, r])
    t.set_zlim3d([-r, r])
    
    f.set_axis_off()
    t.set_axis_off()
    
    fig.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
                hspace = 0, wspace = 0)
    
    plt.draw()
    plt.show()
    

    This will give tighter subplots, as the defaults for SubplotParams are as follows:

    left : 0.125

    right : 0.9

    bottom : 0.1

    top : 0.9

    wspace : 0.2

    hspace : 0.2

    not sure it is this the OP is looking for though...

    0 讨论(0)
  • 2021-01-07 19:03

    Since you want rectangular plot, you cannot use set_aspect('equal'), instead you have to adjust the limits of your plots to account for the difference in aspect ratios.

    In the attempt below, I've used the bbox of the axis to get the height and width of the axes and used the aspect ratio to rescale X and Y axes. (I assumed both plots have the same dimension, but uou could also have plots with different dimensions, you'll just have to adjust the axes limits independently for each one).

    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    
    fig = plt.figure()
    f = fig.add_subplot(2, 1, 1, projection='3d')
    t = fig.add_subplot(2, 1, 2, projection='3d')
    
    # axes
    for d in {f, t}:
        d.plot([-1, 1], [0, 0], [0, 0], color='k', alpha=0.8, lw=2)
        d.plot([0, 0], [-1, 1], [0, 0], color='k', alpha=0.8, lw=2)
        d.plot([0, 0], [0, 0], [-1, 1], color='k', alpha=0.8, lw=2)
    
    f.dist = t.dist = 5.2   # 10 is default
    
    plt.tight_layout()
    # Cannot use 'equal' aspect for a rectangular plot
    # f.set_aspect('equal')
    # t.set_aspect('equal')
    
    # get the dimensions of the axes from its bbox
    f_bbox = f.get_position()
    f_height = f_bbox.height
    f_width = f_bbox.width
    
    
    r = 6
    f.set_xlim3d([-1 * f_width/f_height * r, f_width/f_height * r])
    f.set_ylim3d([-1 * f_width/f_height * r, f_width/f_height * r])
    f.set_zlim3d([-r, r])
    
    t.set_xlim3d([-1 * f_width/f_height * r, f_width/f_height * r])
    t.set_ylim3d([-1 * f_width/f_height * r, f_width/f_height * r])
    t.set_zlim3d([-r, r])
    
    f.set_axis_off()
    t.set_axis_off()
    
    plt.draw()
    plt.show()
    

    Note: In this picture, I've added a background color to highlight the rectangular shape of the plots

    0 讨论(0)
提交回复
热议问题