5

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()

これはデータの小さなサンプルのプロットです - ここに画像の説明を入力

上記のプロットの領域の 1 つを詳しく見てみましょう (重なっている/交差している線に注意してください) - ここに画像の説明を入力

等高線図のように見えない理由がわかりません。線が交差していますが、これは起こるべきではありません。何が間違っている可能性がありますか?助けてください。

4

1 に答える 1

6

次のコードを使用してみてください。これはあなたを助けるかもしれません-それはクックブックにあったのと同じものです:

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()

2Dのガウス分布を使用してサンプル出力ファイルを作成しました。上記のコードを使用した私の結果:

2Dでのガウス分布

ノート:

エッジがトリミングされていることに気づいたかもしれません。これは、griddata-functionがマスクされた配列を作成するためです。つまり、プロットの境界は外側の点によって作成されます。国境の外にあるものはすべてありません。ポイントが線上にある場合、プロットするための等高線はありません。これは一種の論理的です。私はそれについて言及します、あなたの4つの投稿されたデータポイントの原因。このケースがある可能性があります。多分あなたはそれを持っていません=)

アップデート

コードを少し編集しました。問題は、入力ファイルの依存関係を正しく解決しなかったことである可能性があります。次のコードを使用すると、プロットは正しく機能するはずです。

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()

このコードと小さなサンプルを使用すると、次のプロットが得られます。

サンプルプロット

私のスニペットを使用して、少し変更してみてください。たとえば、指定されたサンプルcsvファイルの区切り文字をからに変更する必要がありまし|,。私があなたのために書いたコードは本当にいいものではありませんが、それはまっすぐな序文で書かれています。

返事が遅くなってごめん。

于 2012-02-29T00:33:23.660 に答える