【问题标题】:Make 3d Python plot as beautiful as Matlab让 3d Python 绘图像 Matlab 一样漂亮
【发布时间】:2021-04-15 03:00:43
【问题描述】:

注意: 这不是一个转换问题。目的是看看Python是否有能力像Matlab一样生成3D绘图。

我创建了一个 Matlab 绘图,如下所示:

我尝试使用 Python 绘制它,但我无法将它与 Matlab 一样好。是否有任何软件包可以将上述内容与原始软件包一样好?如果是,请将我的代码转换为 Python 版本。这是我的 Matlab 代码。

set(groot,'defaultAxesTickLabelInterpreter','latex');  
set(groot,'defaulttextinterpreter','latex');
set(groot,'defaultLegendInterpreter','latex');
x0=0;
y0=0;
width=3000;
height=2000;
set(gcf,'position',[x0,y0,width,height])
[X,Y] = meshgrid(-1:.01:1);
a = 3;
b = 2;
Z = a*X.^2 + b*Y.^2;
subplot(1,3,1)
s = surf(X,Y,Z,'FaceColor','r', 'FaceAlpha',0.5, 'EdgeColor','none');
s.EdgeColor = 'none';
xlabel('$x_1$','Interpreter','latex','FontSize', 15)
ylabel('$x_2$','Interpreter','latex','FontSize', 15)
zlabel('$f(\mathbf{x};\mathbf{\theta})$','Interpreter','latex','FontSize', 15)
legend({'$f([x_1, x_2]^\top; [\theta_1=3,\theta_2=2]^\top)=3x_1^2+2x_2^2$'},'interpreter','latex','FontSize', 10)
subplot(1,3,2)
Z2 = a*X.^2 ;
s2 = surf(X,Y,Z2,'FaceColor','b', 'FaceAlpha',0.5, 'EdgeColor','none');
s2.EdgeColor = 'none';
xlabel('$x_1$','Interpreter','latex','FontSize', 15)
ylabel('$x_2$','Interpreter','latex','FontSize', 15)
zlabel('$f(\mathbf{x};\mathbf{\theta})$','Interpreter','latex','FontSize', 15)
legend({'$f([x_1, x_2]^\top; [\theta_1=3,\theta_2=0]^\top)=3x_1^2$'},'interpreter','latex','FontSize', 10)
subplot(1,3,3)
s3 = surf(X,Y,Z,'FaceColor','r', 'FaceAlpha',0.5, 'EdgeColor','none');
s3.EdgeColor = 'none';
hold
s4 = surf(X,Y,Z2,'FaceColor','b', 'FaceAlpha',0.5, 'EdgeColor','none');
s4.EdgeColor = 'none';
xlabel('$x_1$','Interpreter','latex','FontSize', 15)
ylabel('$x_2$','Interpreter','latex','FontSize', 15)
zlabel('$f(\mathbf{x};\mathbf{\theta})$','Interpreter','latex','FontSize', 15)
legend({'$f(\mathbf{x};\mathbf{\theta})=3x_1^2+2x_2^2$', '$f(\mathbf{x};\mathbf{\theta})=3x_1^2$'},'interpreter','latex','FontSize', 10)

【问题讨论】:

  • @Eric Leschinski:虽然我要求转换它,但任何转换都是不可接受的,因为我想看看 Python 是否有能力像 Matlab 一样生成 3D 绘图?
  • @Eric Leschinski:感谢您指出该页面。我可以使用 Matlab 使该页面上的图片比该页面上的图片更漂亮:)
  • @Sepide 如果您关心渲染性能,您可能有兴趣查看我的答案

标签: python matplotlib matlab-figure


【解决方案1】:

是的。

numpy + plotly 是一个有效的 Matlab 替代品——你可能会认出其中的一些代码 :)。作为一个好处,这些图呈现为 html,这意味着它们具有高度的可移植性,可以保存为单个文件,并且可以嵌入到网页中。可能有一些不同的小细节(我不知道乳胶轴标签的当前状态),但是,如果你安装了 python、numpy 和 plotly,以下是你第一个 plot 的一个很好的替代:

import plotly.graph_objects as go
import numpy as np

x = np.arange(-1,1,.01)
y = np.arange(-1,1,.01)
X,Y = np.meshgrid(x,y)
a = 3
b = 2
Z = a*X**2 + b*Y**2

fig = go.Figure(
    data=[go.Surface(z=Z, x=x, y=y, colorscale="Reds", opacity=0.5)])
fig.update_layout(
    title='My title', 
    autosize=False,
    width=500, 
    height=500,
    margin=dict(l=65, r=50, b=65, t=90), 
    scene_aspectmode='cube'
)
fig.show()

请注意,python 中的首选绘图包是 Matplotlib。 IMO,它继承了 Matlab 绘图中所有最糟糕的部分,但没有一个好的部分(高性能渲染)。从性能(尤其是 3D 渲染)、交互性和 API 的角度来看,都非常出色。

【讨论】:

  • 我通常使用ax, fig = plt.subplots() 并使用ax 做任何我想做的事情,比如图例等。我可以按照我描述的方式做任何事情吗?
  • 我相信plotly支持子图等。文档很友好,而且例子很多。
【解决方案2】:

对于 Python 中的 3D 图表,我使用 matplotlib.pyplot 获得了最好的结果。

#!/usr/bin/python3 
# -*- coding: utf-8 -*-   
import matplotlib.pyplot as plt  
from mpl_toolkits.mplot3d.axes3d import Axes3D, get_test_data  
from matplotlib import cm   
import numpy as np   
import random  
X_k_list = range(1, 100, 10)  
Y_p_list = [ float(x)/100.0 for x in range(1, 100, 10) ]   
# set up a figure twice as wide as it is tall  
fig = plt.figure(figsize=plt.figaspect(0.5))  
# set up the axes for the first plot  
ax = fig.add_subplot(1, 1, 1, projection='3d')  
# plot a 3D surface like in the example mplot3d/surface3d_demo  
X, Y = np.meshgrid(X_k_list, Y_p_list)  
def critical_function(b, c):  
    num = random.uniform(0, 1) * 10.0  
    return num + (b * c)   
  
Z_accuracy = X.copy()  
Z_accuracy = Z_accuracy.astype(np.float32)  
for i in range(len(X_k_list)):  
    for j in range(len(Y_p_list)):  
        Z_accuracy[j][i] = critical_function(Y_p_list[j], X_k_list[i])  
  
surf = ax.plot_surface(X, Y, Z_accuracy,   
    rstride=1, cstride=1, cmap=cm.coolwarm,  
    linewidth=0, antialiased=False)  
  
ax.set_xlabel('X')  
ax.set_ylabel('Y')  
ax.set_zlabel('Z')  
fig.colorbar(surf, shrink=0.5, aspect=10)  
plt.show()  

https://www.python-graph-gallery.com/371-surface-plot

您可以通过添加更多数据点来增加图表的平滑度,使用鼠标沿 x、y、z 轴旋转图表,还可以添加标题、图例和其他吸引眼球的东西。

ma​​tplotlib.mplot3d 看起来像欧几里得连续曲面

#!/usr/bin/python3 
# -*- coding: utf-8 -*- 
from mpl_toolkits.mplot3d import axes3d 
import matplotlib.pyplot as plt 
from matplotlib import cm 
ax = plt.figure().add_subplot(projection='3d') 
X, Y, Z = axes3d.get_test_data(0.05) 
cset = ax.contour(X, Y, Z, extend3d=True, cmap=cm.coolwarm) 
ax.clabel(cset, fontsize=9, inline=True) 
plt.show() 

https://matplotlib.org/stable/gallery/mplot3d/contour3d_2.html#sphx-glr-gallery-mplot3d-contour3d-2-py

您正在使用 matlab 的 meshgrid(...) 工具生成 x,y,z 数据。 Python 可以通过将numpy.meshgrid 输入matplotlib.pyplot 从而实现相同的结果。

#!/usr/bin/python3 
# -*- coding: utf-8 -*- 
import numpy as np 
import matplotlib.pyplot as plt 
def f(x, y): 
    return np.sin(np.sqrt(x ** 2 + y ** 2)) 
x = np.linspace(-6, 6, 30) 
y = np.linspace(-6, 6, 30) 
X, Y = np.meshgrid(x, y) 
Z = f(X, Y) 
fig = plt.figure() 
ax = plt.axes(projection='3d') 
ax.contour3D(X, Y, Z, 50, cmap='binary') 
ax.set_xlabel('x') 
ax.set_ylabel('y') 
ax.set_zlabel('z') 
plt.show() 

https://jakevdp.github.io/PythonDataScienceHandbook/04.12-three-dimensional-plotting.html

【讨论】:

  • 感谢您的帮助。对此,我真的非常感激。我可以请您使用我的一个表面,以便我更好地了解如何按照您的代码 sn-p 进行操作吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2020-08-13
  • 1970-01-01
相关资源
最近更新 更多