Zeichnen Sie eine glatte Linie mit PyPlot


111

Ich habe das folgende einfache Skript, das ein Diagramm darstellt:

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

So wie es jetzt ist, geht die Linie direkt von Punkt zu Punkt, was in Ordnung aussieht, aber meiner Meinung nach besser sein könnte. Ich möchte die Linie zwischen den Punkten glätten. In Gnuplot hätte ich mit geplottet smooth cplines.

Gibt es eine einfache Möglichkeit, dies in PyPlot zu tun? Ich habe einige Tutorials gefunden, aber alle scheinen ziemlich komplex zu sein.

Antworten:


166

Sie können scipy.interpolate.splineIhre Daten selbst glätten:

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 ist in Scipy 0.19.0 veraltet. Verwenden Sie stattdessen die BSpline-Klasse.

Das Wechseln von splinezu BSplineist kein einfaches Kopieren / Einfügen und erfordert einige Anpassungen:

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

Vor: Screenshot 1

Nach dem: Screenshot 2


2
Haha, das war nicht schwer. Prost! :) Nur ein Hinweis für andere, die vielleicht suchen: Ich musste scipy importieren, um linspace () zu verwenden.
Paul

Ups, sorry, hätte verwenden sollen np.linspace. In meiner Antwort korrigiert.
Olivier Verdier

2
Die 300 gibt an, wie viele Punkte zwischen T.min () und T.max () zu machen sind. Ich habe 1000 verwendet und es sieht genauso aus. Versuchen Sie es mit 5 und Sie werden einen Unterschied sehen.
CornSmith

2
splineist veraltet! Spline ist in scipy 0.19.0 veraltet, verwenden Sie stattdessen die BSpline-Klasse:from scipy.interpolate import BSpline
user890739

2
Dies funktioniert nicht, wenn das T nicht sortiert ist. Und auch wenn die Funktion (T) nicht eins zu eins ist.
Rahat Zaman

28

In diesem Beispiel funktioniert Spline gut, aber wenn die Funktion von Natur aus nicht glatt ist und Sie eine geglättete Version wünschen, können Sie auch Folgendes versuchen:

from scipy.ndimage.filters import gaussian_filter1d

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

Wenn Sie Sigma erhöhen, können Sie eine geglättete Funktion erhalten.

Gehen Sie mit diesem vorsichtig vor. Es ändert die ursprünglichen Werte und entspricht möglicherweise nicht Ihren Wünschen.


10
Gehen Sie mit diesem vorsichtig vor. Es ändert die ursprünglichen Werte und entspricht möglicherweise nicht Ihren Wünschen.
tartaruga_casco_mole

8

Ich nehme an, Sie meinen Kurvenanpassung und nicht Anti-Aliasing aus dem Kontext Ihrer Frage. PyPlot hat keine eingebaute Unterstützung für diese, aber Sie können einige grundlegende Kurvenanpassung sich leicht implementieren, wie der Code gesehen hier , oder wenn Sie mit GuiQwt eine Kurvenanpassung hat Modul . (Sie könnten wahrscheinlich auch den Code von SciPy stehlen , um dies zu tun).


Vielen Dank. Ich habe zehn verschiedene Gleichungen ausprobiert und [Radiale Basisfunktionen zum Glätten / Interpolieren verwenden] [1] rbf = Rbf(x, y), fi = rbf(xi)war am besten unter ihnen. [1]: scipy-cookbook.readthedocs.io/items/RadialBasisFunctions.html ,
Cloud Cho

1

In der scipy.interpolateDokumentation finden Sie einige Beispiele.

Das folgende Beispiel zeigt die Verwendung für die lineare und kubische Spline-Interpolation:

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

Geben Sie hier die Bildbeschreibung ein

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.