【问题标题】:Matplotlib contour plot with intersecting contour linesMatplotlib 等高线图与相交的等高线
【发布时间】:2012-02-26 12:12:27
【问题描述】:

我正在尝试在 python 中使用 matplotlib 绘制以下数据的等高线图。数据是这种形式-

# x       y      height
  77.23  22.34     56
  77.53  22.87     63
  77.37  22.54     72
  77.29  22.44     88

数据实际上包含近 10,000 个点,我是从输入文件中读取的。然而,z 的不同可能值的集合很小(在 50-90 之间,整数),我希望每个这样不同的 z 都有一个等高线。

这是我的代码 -

import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
import csv
import sys

# read data from file
data = csv.reader(open(sys.argv[1], 'rb'), delimiter='|', quotechar='"')
x = []
y = []
z = []

for row in data:
    try:
        x.append(float(row[0]))
        y.append(float(row[1]))
        z.append(float(row[2]))
    except Exception as e:
        pass
        #print e

X, Y = np.meshgrid(x, y)        # (I don't understand why is this required)

# creating a 2D array of z whose leading diagonal elements
# are the z values from the data set and the off-diagonal
# elements are 0, as I don't care about them.
z_2d = []
default = 0
for i, no in enumerate(z):
    z_temp = []
    for j in xrange(i): z_temp.append(default)
    z_temp.append(no)
    for j in xrange(i+1,  len(x)): z_temp.append(default)
    z_2d.append(z_temp)
Z = z_2d

CS = plt.contour(X, Y, Z, list(set(z)))
plt.figure()
CB = plt.colorbar(CS, shrink=0.8, extend='both')
plt.show()

这是一小部分数据的图 -

这是对上图区域之一的仔细观察(注意重叠/相交的线) -

我不明白为什么它看起来不像等高线图。线相交,这不应该发生。什么可能是错的?请帮忙。

【问题讨论】:

    标签: python matplotlib contour


    【解决方案1】:

    尝试使用以下代码。这可能会对您有所帮助——这与 Cookbook 中的内容相同:

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.mlab import griddata
    
    # with this way you can load your csv-file really easy -- maybe you should change
    # the last 'dtype' to 'int', because you said you have int for the last column
    data = np.genfromtxt('output.csv', dtype=[('x',float),('y',float),('z',float)],
                         comments='"', delimiter='|')
    
    # just an assigning for better look in the plot routines
    x = data['x']
    y = data['y']
    z = data['z']
    
    # just an arbitrary number for grid point
    ngrid = 500
    
    # create an array with same difference between the entries
    # you could use x.min()/x.max() for creating xi and y.min()/y.max() for yi
    xi = np.linspace(-1,1,ngrid)
    yi = np.linspace(-1,1,ngrid)
    
    # create the grid data for the contour plot
    zi = griddata(x,y,z,xi,yi)
    
    # plot the contour and a scatter plot for checking if everything went right
    plt.contour(xi,yi,zi,20,linewidths=1)
    plt.scatter(x,y,c=z,s=20)
    plt.xlim(-1,1)
    plt.ylim(-1,1)
    plt.show()
    

    我创建了一个具有二维高斯分布的示例输出文件。我使用上面代码的结果:

    注意:

    也许您注意到边缘有点被裁剪了。这是因为griddata-函数创建了屏蔽数组。我的意思是情节的边界是由外部点创建的。边界之外的一切都不存在。如果您的点在一条线上,那么您将没有任何用于绘图的轮廓。这有点合乎逻辑。我提到它,因为您发布了四个数据点。您似乎有这种情况。也许你没有它=)

    更新

    我稍微编辑了代码。您的问题可能是您没有正确解决输入文件的依赖关系。使用以下代码,绘图应该可以正常工作。

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.mlab import griddata
    import csv
    
    data = np.genfromtxt('example.csv', dtype=[('x',float),('y',float),('z',float)],
                         comments='"', delimiter=',')
    
    sample_pts = 500
    con_levels = 20
    
    x = data['x']
    xmin = x.min()
    xmax = x.max()
    
    y = data['y']
    ymin = y.min()
    ymax = y.max()
    
    z = data['z']
    
    xi = np.linspace(xmin,xmax,sample_pts)
    yi = np.linspace(ymin,ymax,sample_pts)
    
    zi = griddata(x,y,z,xi,yi)
    
    plt.contour(xi,yi,zi,con_levels,linewidths=1)
    plt.scatter(x,y,c=z,s=20)
    plt.xlim(xmin,xmax)
    plt.ylim(ymin,ymax)
    plt.show()
    

    使用此代码和您的小样本,我得到以下图:

    尝试使用我的 sn-p 并稍微更改一下。例如,对于给定的示例 csv 文件,我必须将分隔符从 | 更改为 ,。我为你写的代码不是很好,但它是直接写的前言。

    抱歉回复晚了。

    【讨论】:

    • 这就是我根据您的代码获取情节的方式 - mediafire.com/?9slrkypn6t9s6qv。这就是我所期望的(使用 Matlab 绘制)-mediafire.com/?3c63voqgol63ubz。有什么建议吗?
    • 我真的看不到任何轮廓线。能不能把数据发给我。然后我可以仔细看看这个问题。
    • 嘿帕特托尼,我真的很感谢你的帮助。我在这里上传了一小部分数据样本 - mediafire.com/download.php?ubnsruoe2yistfk。 (请注意 - 预期等高线图上面的链接是整个数据,而不是我上传的这个样本。)
    • 感谢您继续提供帮助。有效!但是,我不明白为什么轮廓显示点,它应该只显示线条。此外,我尝试绘制完整的数据,但它给出了一个错误(KeyError:4002)。我在网上发现它可能特定于 Ubuntu,而不是你的代码。不过,你可以试一试,让我知道它是否对你有用。我已经在这里上传了数据,如果你想试试 - mediafire.com/?o4ayhx2lvs4vhys。再次感谢您的帮助。
    • KeyError 是由于某些NaN 值造成的。如果你检查你的输入文件(你发给我的那个)。你会发现有些行没有内容。这就是你有问题的原因。如果您不想有点,请评论命令plt.scatter(x,y,c=z,s=20)。我用它来检查轮廓是否正确。我会写一些关于你的代码的东西。只是需要更多时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 1970-01-01
    • 2017-02-15
    相关资源
    最近更新 更多