2011-11-08 28 views
2

Matplotlibを使って等高線図を作成しています。私は多次元配列のデータ をすべて持っています。それは2000年頃の12の長さです。したがって、 は基本的に2000の長さの12リストのリストです。私はコンタープロット が問題なく動作していますが、データを滑らかにする必要があります。私はたくさんの例を 読みました。残念ながら、私は が何をしているのかを理解するための数学の背景がありません。Matplotlibで等高線図のデータを平滑化

どうすればこのデータをスムーズにすることができますか?私はグラフが のように見えて、私はそれをもっと見たいと思っています。

これは私のグラフである:

graph illustration

私はそれがあまりにも多くの類似した見たいもの:

私は2番目のように等高線図を滑らかにする必要がありますどのような手段

my goal

プロット?


私が使用しているデータは、XMLファイルから取得されています。しかし、配列の一部に の出力を示します。配列内の各要素は約2000項目の長さであるため、I は抜粋のみを表示します。ここで

はサンプルです:

[27.899999999999999, 27.899999999999999, 27.899999999999999, 27.899999999999999, 
28.0, 27.899999999999999, 27.899999999999999, 28.100000000000001, 28.100000000000001, 
28.100000000000001, 28.100000000000001, 28.100000000000001, 28.100000000000001, 
28.100000000000001, 28.100000000000001, 28.0, 28.100000000000001, 28.100000000000001, 
28.0, 28.100000000000001, 28.100000000000001, 28.100000000000001, 28.100000000000001, 
28.100000000000001, 28.100000000000001, 28.100000000000001, 28.100000000000001, 
28.100000000000001, 28.100000000000001, 28.100000000000001, 28.100000000000001, 
28.100000000000001, 28.100000000000001, 28.100000000000001, 28.100000000000001, 
28.100000000000001, 28.100000000000001, 28.0, 27.899999999999999, 28.0, 
27.899999999999999, 27.800000000000001, 27.899999999999999, 27.800000000000001, 
27.800000000000001, 27.800000000000001, 27.899999999999999, 27.899999999999999, 28.0, 
27.800000000000001, 27.800000000000001, 27.800000000000001, 27.899999999999999, 
27.899999999999999, 27.899999999999999, 27.899999999999999, 28.0, 28.0, 28.0, 28.0, 
28.0, 28.0, 28.0, 28.0, 27.899999999999999, 28.0, 28.0, 28.0, 28.0, 28.0, 
28.100000000000001, 28.0, 28.0, 28.100000000000001, 28.199999999999999, 
28.300000000000001, 28.300000000000001, 28.300000000000001, 28.300000000000001, 
28.300000000000001, 28.399999999999999, 28.300000000000001, 28.300000000000001, 
28.300000000000001, 28.300000000000001, 28.300000000000001, 28.300000000000001, 
28.399999999999999, 28.399999999999999, 28.399999999999999, 28.399999999999999, 
28.399999999999999, 28.300000000000001, 28.399999999999999, 28.5, 28.399999999999999, 
28.399999999999999, 28.399999999999999, 28.399999999999999] 

は、これが唯一の抜粋である点に注意してください。データの次元は12行、 1959列です。列は、XML ファイルからインポートされたデータに応じて変わります。私はGaussian_filterを使用した後に値を見ることができ、彼らは を変更します。しかし、その変化は等高線プロットに影響を与えるほど大きくはありません。

答えて

10

あなたはgaussian_filterでデータをスムーズにできます。

import numpy as np 
import matplotlib.pyplot as plt 
import scipy.ndimage as ndimage 

X, Y = np.mgrid[-70:70, -70:70] 
Z = np.cos((X**2+Y**2)/200.)+ np.random.normal(size=X.shape) 

# Increase the value of sigma to increase the amount of blurring. 
# order=0 means gaussian kernel 
Z2 = ndimage.gaussian_filter(Z, sigma=1.0, order=0) 
fig=plt.figure() 
ax=fig.add_subplot(1,2,1) 
ax.imshow(Z) 
ax=fig.add_subplot(1,2,2) 
ax.imshow(Z2) 
plt.show() 

enter image description here

左側は元のデータ、ガウスフィルタ後の右側を示しています。

上記のコードの多くは、手作りのガウスカーネルを使ったガウス平滑化を示すScipy Cookbookから取られました。 scipyには同じものが組み込まれているので、私はgaussian_filterを使いました。

+0

私は以前この例を見てきました。しかし、私は私の配列でこれを動作させることができません。私の配列は、数字の配列ではなく、Pythonのリストであることに注意してください。これは問題を引き起こすでしょうか?もしそうなら、Pythonリストをnumpy配列に変換する最も簡単な方法は何ですか? – dman87

+0

実際には、ndimage.gaussian_filterは実際にうまく動作するリストのリストを操作できます。 (例えば、 'ndimage.gaussian_filter(Z.tolist())'はうまくいきます)。問題は別の場所になければなりません。データを見ずに言うのは難しい。何がうまくいかないの?例外が発生していますか?または結果はちょうど正しく見えませんか? – unutbu

+0

申し訳ありませんが、私はより具体的であったはずです。私はそれがリスト内の文字列であることが問題であったと信じています。しかし、contour()関数はそれについて不平を言っていませんでした。 エラーなしで動作させることができました。しかし、contour()の出力はまったく変更されません。 – dman87

7

データを平滑化する簡単な方法の1つは、moving averageアルゴリズムです。移動平均の1つの簡単な形式は、特定の位置での隣接測定値の平均を計算することです。例えば、a [n] =(a [n-1] + a [n] + a [n])として移動平均を計算することができる。 n + 1])/ 3となる。あなたがあなたのすべての測定を終えると、あなたは完了です。この単純な例では、平均化ウィンドウのサイズは3です。また、どれだけ平滑化したいかによって、サイズの異なるウィンドウを使用することもできます。

より広い範囲のアプリケーションで計算を簡単かつ迅速に行うには、convolutionに基づくアルゴリズムを使用することもできます。コンボリューションを使用する利点は、単純にウィンドウを変更するだけで、加重平均のような異なる種類の平均を選択できることです。

説明のためにコーディングをしましょう。次の抜粋は、Numpy、Matplotlib、Scipyがインストールされている必要があります。フル走行サンプルコードのClick here

from __future__ import division 
import numpy 
import pylab 
from scipy.signal import convolve2d 

def moving_average_2d(data, window): 
    """Moving average on two-dimensional data. 
    """ 
    # Makes sure that the window function is normalized. 
    window /= window.sum() 
    # Makes sure data array is a numpy array or masked array. 
    if type(data).__name__ not in ['ndarray', 'MaskedArray']: 
     data = numpy.asarray(data) 

    # The output array has the same dimensions as the input data 
    # (mode='same') and symmetrical boundary conditions are assumed 
    # (boundary='symm'). 
    return convolve2d(data, window, mode='same', boundary='symm') 

次のコードは、いくつかの任意のノイズの多いデータを生成し、四つの異なるサイズのボックスウィンドウを使用して、移動平均値を算出します。

M, N = 20, 2000 # The shape of the data array 
m, n = 3, 10  # The shape of the window array 

y, x = numpy.mgrid[1:M+1, 0:N] 
# The signal and lots of noise 
signal = -10 * numpy.cos(x/500 + y/10)/y 
noise = numpy.random.normal(size=(M, N)) 
z = signal + noise 

# Calculating a couple of smoothed data. 
win = numpy.ones((m, n)) 
z1 = moving_average_2d(z, win) 
win = numpy.ones((2*m, 2*n)) 
z2 = moving_average_2d(z, win) 
win = numpy.ones((2*m, 4*n)) 
z3 = moving_average_2d(z, win) 
win = numpy.ones((2*m, 10*n)) 
z4 = moving_average_2d(z, win) 

次に、さまざまな結果を確認するために、いくつかのプロットのコードを示します。

# Initializing the plot 
pylab.close('all') 
pylab.ion() 
fig = pylab.figure() 
bbox = dict(edgecolor='w', facecolor='w', alpha=0.9) 
crange = numpy.arange(-15, 16, 1.) # color scale data range 

# The plots 
ax = pylab.subplot(2, 2, 1) 
pylab.contourf(x, y, z, crange) 
pylab.contour(x, y, z1, crange, colors='k') 
ax.text(0.05, 0.95, 'n=10, m=3', ha='left', va='top', transform=ax.transAxes, 
    bbox=bbox) 

bx = pylab.subplot(2, 2, 2, sharex=ax, sharey=ax) 
pylab.contourf(x, y, z, crange) 
pylab.contour(x, y, z2, crange, colors='k') 
bx.text(0.05, 0.95, 'n=20, m=6', ha='left', va='top', transform=bx.transAxes, 
    bbox=bbox) 

bx = pylab.subplot(2, 2, 3, sharex=ax, sharey=ax) 
pylab.contourf(x, y, z, crange) 
pylab.contour(x, y, z3, crange, colors='k') 
bx.text(0.05, 0.95, 'n=40, m=6', ha='left', va='top', transform=bx.transAxes, 
    bbox=bbox) 

bx = pylab.subplot(2, 2, 4, sharex=ax, sharey=ax) 
pylab.contourf(x, y, z, crange) 
pylab.contour(x, y, z4, crange, colors='k') 
bx.text(0.05, 0.95, 'n=100, m=6', ha='left', va='top', transform=bx.transAxes, 
    bbox=bbox) 

ax.set_xlim([x.min(), x.max()]) 
ax.set_ylim([y.min(), y.max()]) 

fig.savefig('movingavg_sample.png') 
# That's all folks! 

そしてここで異なるサイズのウィンドウについてプロットした結果である:Results

は、ここで与えられたサンプルコードは、単純なボックス(または長方形)を使用して二次元の窓。いくつかの異なる種類のウィンドウがあり、さらに多くの例についてはWikipediaをチェックしてください。

関連する問題