4

Matplotlib を使用して等高線図を作成しています。多次元の配列にすべてのデータがあります。長さ12、幅約2000です。したがって、基本的には、長さが 2000 の 12 個のリストのリストです。等高線図は正常に機能していますが、データを平滑化する必要があります。私はたくさんの例を読みました。残念ながら、私は彼らに何が起こっているのかを理解するための数学の知識がありません。

では、どうすればこのデータを平滑化できますか? グラフがどのように見えるか、どのように見せたいかの例があります。

これは私のグラフです:

グラフの図

私ももっと似てほしいもの:

私の目標

2番目のプロットのように等高線プロットを滑らかにする必要があるのはどういう意味ですか?


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

以下にサンプルを示します。

[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 行 x 1959 列です。列は、XML ファイルからインポートされたデータに応じて変化します。Gaussian_filter を使用した後に値を確認すると、値が変化します。しかし、変化はコンター プロットに影響を与えるほど大きくはありません。

4

2 に答える 2

12

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

ここに画像の説明を入力

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

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

于 2011-11-08T19:13:46.907 に答える
9

データを平滑化する簡単な方法の 1 つは、移動平均アルゴリズムを使用することです。移動平均の単純な形式の 1 つは、特定の位置で隣接する測定値の平均を計算することです。たとえば、1 次元の一連の測定値 a[1:N] では、a[n] での移動平均は、a[n] = (a[n-1] + a[n] + a[ n+1]) / 3、たとえば。すべての測定を実行したら、完了です。この単純な例では、平均化ウィンドウのサイズは 3 です。必要な平滑化の程度に応じて、さまざまなサイズのウィンドウを使用することもできます。

より広い範囲のアプリケーションで計算をより簡単かつ高速にするために、畳み込みに基づくアルゴリズムを使用することもできます。畳み込みを使用する利点は、ウィンドウを変更するだけで、加重平均などのさまざまな種類の平均を選択できることです。

説明するためにいくつかのコーディングを行いましょう。次の抜粋では、Numpy、Matplotlib、および Scipy がインストールされている必要があります。完全な実行サンプル コードについては、ここをクリックしてください

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

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

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!

以下は、さまざまなサイズのウィンドウの結果をプロットしたものです。結果

ここに示すサンプル コードでは、単純なボックス (または長方形) ウィンドウを 2 次元で使用しています。使用可能なウィンドウにはいくつかの異なる種類があり、ウィキペディアでさらに例を確認することをお勧めします。

于 2011-11-13T23:12:09.930 に答える