Plot garis mulus dengan PyPlot

112

Saya punya skrip sederhana berikut yang memplot grafik:

import matplotlib.pyplot as plt
import numpy as np

T = np.array([6, 7, 8, 9, 10, 11, 12])
power = np.array([1.53E+03, 5.92E+02, 2.04E+02, 7.24E+01, 2.72E+01, 1.10E+01, 4.70E+00])

plt.plot(T,power)
plt.show()

Seperti sekarang, garis lurus dari titik ke titik yang terlihat baik-baik saja, tetapi menurut saya bisa lebih baik. Yang saya inginkan adalah menghaluskan garis di antara titik-titik. Di Gnuplot saya akan merencanakan dengan smooth cplines.

Apakah ada cara mudah untuk melakukan ini di PyPlot? Saya telah menemukan beberapa tutorial, tetapi semuanya tampak agak rumit.

Paul
sumber

Jawaban:

167

Anda dapat menggunakan scipy.interpolate.splineuntuk memuluskan data Anda sendiri:

from scipy.interpolate import spline

# 300 represents number of points to make between T.min and T.max
xnew = np.linspace(T.min(), T.max(), 300)  

power_smooth = spline(T, power, xnew)

plt.plot(xnew,power_smooth)
plt.show()

spline tidak digunakan lagi di scipy 0.19.0, gunakan kelas BSpline sebagai gantinya.

Beralih dari splineke BSplinebukanlah salin / tempel langsung dan membutuhkan sedikit penyesuaian:

from scipy.interpolate import make_interp_spline, BSpline

# 300 represents number of points to make between T.min and T.max
xnew = np.linspace(T.min(), T.max(), 300) 

spl = make_interp_spline(T, power, k=3)  # type: BSpline
power_smooth = spl(xnew)

plt.plot(xnew, power_smooth)
plt.show()

Sebelum: tangkapan layar 1

Setelah: tangkapan layar 2

Olivier Verdier
sumber
2
Haha, itu tidak sulit. Bersulang! :) Sekadar catatan untuk orang lain yang mungkin mencari: Saya harus mengimpor scipy untuk menggunakan linspace ().
Paul
Ups, maaf, seharusnya sudah digunakan np.linspace. Dikoreksi dalam jawaban saya.
Olivier Verdier
2
300 adalah berapa banyak poin yang harus dibuat antara T.min () dan T.max (). Saya menggunakan 1000 dan terlihat sama. Coba dengan 5 dan Anda akan melihat perbedaannya.
CornSmith
2
splinesudah ditinggalkan! spline tidak digunakan lagi di scipy 0.19.0, gunakan kelas BSpline sebagai gantinya:from scipy.interpolate import BSpline
user890739
2
Ini tidak akan bekerja jika T tidak diurutkan. Dan juga jika functiton (T) tidak one-to-one.
Rahat Zaman
28

Untuk contoh ini, spline berfungsi dengan baik, tetapi jika fungsinya tidak mulus secara inheren dan Anda ingin versi yang dihaluskan, Anda juga dapat mencoba:

from scipy.ndimage.filters import gaussian_filter1d

ysmoothed = gaussian_filter1d(y, sigma=2)
plt.plot(x, ysmoothed)
plt.show()

jika Anda meningkatkan sigma, Anda bisa mendapatkan fungsi yang lebih halus.

Lanjutkan dengan hati-hati dengan yang ini. Ini mengubah nilai asli dan mungkin bukan yang Anda inginkan.

Sajad Norouzi
sumber
10
Lanjutkan dengan hati-hati dengan yang ini. Ini mengubah nilai asli dan mungkin bukan yang Anda inginkan.
tartaruga_casco_mole
8

Saya kira yang Anda maksud adalah pencocokan kurva dan bukan anti-aliasing dari konteks pertanyaan Anda. PyPlot tidak memiliki dukungan bawaan untuk ini, tetapi Anda dapat dengan mudah menerapkan beberapa penyesuaian kurva dasar, seperti kode yang terlihat di sini , atau jika Anda menggunakan GuiQwt, ia memiliki modul pemasangan kurva . (Anda mungkin juga bisa mencuri kode dari SciPy untuk melakukan ini juga).

Nick Bastin
sumber
Terima kasih. Saya mencoba sepuluh persamaan berbeda dan [Menggunakan fungsi basis radial untuk penghalusan / interpolasi] [1] rbf = Rbf(x, y), fi = rbf(xi)adalah yang terbaik di antara persamaan-persamaan tersebut . [1]: scipy-cookbook.readthedocs.io/items/RadialBasisFunctions.html ,
Cloud Cho
1

Lihat scipy.interpolatedokumentasi untuk beberapa contoh.

Contoh berikut menunjukkan penggunaannya, untuk interpolasi linear dan kubik spline:

>>> from scipy.interpolate import interp1d

>>> x = np.linspace(0, 10, num=11, endpoint=True)
>>> y = np.cos(-x**2/9.0)
>>> f = interp1d(x, y)
>>> f2 = interp1d(x, y, kind='cubic')

>>> xnew = np.linspace(0, 10, num=41, endpoint=True)
>>> import matplotlib.pyplot as plt
>>> plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--')
>>> plt.legend(['data', 'linear', 'cubic'], loc='best')
>>> plt.show()

masukkan deskripsi gambar di sini

Mateen Ulhaq
sumber