如何正确设置轴视图以保持Matplotlib中数据的比例不变?

时间:2019-07-19 15:47:08

标签: python matplotlib

我实际上正在尝试使用matplotlib的Axes3D类在同一场景中绘制两个Planet。使用方法ploth_surface()绘制两个行星。 我想在图中保留行星之间的实际距离和行星的实际尺寸。 为了更好地解释您的问题,假设这两个球的中心在x方向上。

问题如下: -如果不手动设置xlim,ylim,zlim,则自动缩放会使行星更靠近,但是当然,由于它们距离太远,因此不再尊重正确的比例,并且沿x方向似乎是平坦的。

  • 如果我使用xlim,ylim,zlim,则为了遵守所有场景比例,我必须将所有轴的限制设置为至少等于两个行星之间的距离,否则它们将再次变得平坦。该方法的问题在于它们在场景中很小。

有没有一种方法可以只设置“视图限制”而不更改场景中的比例?

我是一个初学者,如果您能给我反馈以逐步说明您的解决方案,我将非常高兴。 此外,我知道Matplotlib并不是3D可视化的最佳绘图库,但是我想在不更改库的情况下解决此问题。

这是我尝试过的:

def plot_sphere(self):
        fig = plt.figure(1)
        ax = Axes3D(fig)
        ax.set_title('TITLE')
        ax.set_xlabel(xlabel = 'X[KM]', labelpad = 15) 
        ax.set_ylabel(ylabel = 'Y[KM]', labelpad = 15) #
        ax.set_zlabel(zlabel = 'Z[KM]', labelpad = 15)

        if self.Plot_m1 is True and self.Plot_m2 is True:
            x1,y1,z1,x2,y2,z2  = self.planet_buider()
            c_m1, c_m2 = self.planet_color()
            ax.plot_surface(x1,y1,z1, cmap = c_m1)
            ax.plot_surface(x2,y2,z2, cmap = c_m2)
        if self.Plot_m1 is False and self.Plot_m2 is True:
            _,_,_,x2,y2,z2 = self.planet_buider()
            _,c_m2 = self.planet_color()
            ax.plot_surface(x2,y2,z2, cmap = c_m2)
        if self.Plot_m1 is True and self.Plot_m2 is False:
            x1,y1,z1,_,_,_  = self.planet_buider()
            c_m1, _ = self.planet_color()  
            ax.plot_surface(x1,y1,z1, cmap = c_m1)
        if self.Plot_m1 is False and self.Plot_m2 is False:
            raise Exception('Input arguments cannot both be false')

        #improve the scaling
        max_scale = ax.get_xlim3d()[1]
        min_scale = ax.get_xlim3d()[0]

        max_list = [ax.get_xlim3d()[1], ax.get_ylim3d()[1], ax.get_zlim3d()[1]]
        min_list = [ax.get_xlim3d()[0], ax.get_ylim3d()[0], ax.get_zlim3d()[0]]

        for index in range(len(max_list)):
            if max_list[index] > max_scale:
                max_scale = max_list[index]
            if min_list[index] < min_scale:
                min_scale = min_list[index]

        #centering the figure
        mean = (max_scale - min_scale)/2

        ax.set_xlim3d(left = min_scale, right = max_scale)
        ax.set_ylim3d(bottom = mean - max_scale , top = max_scale - mean )
        ax.set_zlim3d(bottom = mean - max_scale , top = max_scale - mean )

0 个答案:

没有答案