使用for循环和范围后的3D绘图(Python)

时间:2014-11-30 22:11:37

标签: python for-loop matplotlib range

我有一些问题,但我找不到任何答案,但我对此有所了解。

  1. 到目前为止,我的代码如下:

     from mpl_toolkits.mplot3d import Axes3D 
     from matplotlib import cm
     from math import *
     from scipy.special import *
     import matplotlib.pyplot as plt
     import numpy as np
    
     ## Definition der Parameter für Druckgleichung nach Rudnicki (1986) ##
     q = 6.0/1000                                                                       
     lameu = 11.2*10**9                              
     lame = 8.4*10**9                               
     pi                                            
     alpha = 0.65                                    
     G = 8.4*10**9                                   
     k = 1.0e-15                                      
     eta = 0.001                                                 
     t = 1000*365*24600        
    
     kappa = k/eta                                                    
     print "kappa ist:",kappa                                        
     c = ((kappa*(lameu-lame)*(lame+2*G))/((alpha**2)*(lameu+2*G)))  
     print "c ist:",c                                                
    
    
     xmin = -10
     xmax = 10
     ymin = -10
     ymax = 10
     for x in range (xmin,xmax):
     for y in range (ymin,ymax):
            r=sqrt(x**2+y**2)
            P=(q/(rhof*4*pi*kappa))*(expn(1,r**2/(4*c*t)))
            z = P/1e6
            print x,  y,  z
    
    
     x, y = np.meshgrid(x, y)
    
    
     ## Plotting in 3D ##
     fig = plt.figure()
     ax = fig.gca(projection='3d')
     surf = ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap=cm.jet, linewidth=0,
                       antialiased=False, vmin=np.nanmin(z), vmax=np.nanmax(z))
     fig.colorbar(surf, shrink=0.5, aspect=5)
    
     ## Achsenskalen ##
     ax.set_xlim(xmin,xmax)      # x-Achsenskala vorgeben
     ax.set_ylim(ymin,ymax)      # y-Achsenskala vorgeben
    
     ## Beschriftung der Achsen ##
     ax.set_title('Druckverteilung')
     ax.set_xlabel('Distanz zu Well [m]')
     ax.set_ylabel('Distanz zu Well [m]')
     ax.set_zlabel('Druck in [MPa]')
    
     plt.show()  
    
  2. 如果我尝试运行该程序,我的x,y和z的值会按预期显示,但我没有得到任何3D图。之前我遇到过这个问题,所以我尝试将z的无限值定义为不是数字:

        z[z==np.inf] = np.nan
    

    将此添加到我的代码后,我收到以下错误: TypeError:' numpy.float64'对象不支持项目分配

    究竟是什么意思?我没有在上下文中得到它。我想我的情节需要它吗?

    1. 我的for循环的确切区别是什么,例如使用:

      for x in range [-10,10]
      

      for x in range (-10,10)
      

    2. 我知道有些类型的函数使用

          P[x,y]=....
      

      而不仅仅是

          P=....
      

      我何时必须使用括号?

      我希望有人可以照亮我。谢谢!

1 个答案:

答案 0 :(得分:1)

回答你的各种问题:

z[z==np.inf] = np.nan
     

将此代码添加到我的代码后,我收到以下错误:TypeError:' numpy.float64'对象没有   支持项目分配

这是因为z只是一个数字,而不是数组。

()[]混淆很简单,您可以使用list括号访问__getitem__(或实现[]的任何其他容器类的元素。您使用call对象()

基本上,这两个语法位是不太方便的版本的简短形式;

myObject[key]会产生myObject.__getitem__(key)myObject(variable)会产生myObject.__call__(variable)。这只是语法。

通常,这些用于创建函数和容器类(您可能会滥用它们,但它会导致一些非常混乱的代码)。

至于制作您的绘图工作,您需要制作具有正确形状的z数据点阵列。

您遇到的问题是您没有按要求向plot_surface提供数据,它需要2D数组数据。 XXYY正是numpy.meshgrid创建的内容,iirc,x和y参数可以只是直接列表,但我还没有尝试过。

无论如何,你通常都有像这样的元素(对于方格):

XX
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9

YY
1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 
3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 
6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8 8
9 9 9 9 9 9 9 9 9

然后ZZ只是相应点上函数的z值,即如果您正在绘制某些函数f(x,y),那么您可以执行以下操作:

for i in range(len(XX)):
  for j in range(len(XX[0])):
    ZZ[i][j] = f(XX[i][j], YY[i][j])

虽然可能会有一些更快的numpy方式来进行更快的数组操作。

我通常做这样的事情:

import numpy
# other boiler plae variable definitions you have
xs = numpy.linspace(xStart, xStop, num=50)
ys = numpy.linspace(yStart, yStop, num=50)

XX, YY = numpy.meshgrid(xs,ys)
ZZ = numpy.zeros_like(XX)

for i, x in enumerate(xs):
  for j, y in enumerate(ys):
    r=sqrt(x**2+y**2)
    P=(q/(rhof*4*pi*kappa))*(expn(1,r**2/(4*c*t)))
    ZZ[i][j] = P/1e6

fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(XX, YY, ZZ, rstride=1, cstride=1, cmap=cm.jet, linewidth=0,
                       antialiased=False, vmin=np.nanmin(ZZ), vmax=np.nanmax(ZZ))
fig.colorbar(surf, shrink=0.5, aspect=5)