Cómo trazar una línea (cadena poligonal) con numpy / scipy / matplotlib con un mínimo de suavizado

Estoy tratando de trazar una línea en matplotlib … Estoy buscando el tipo correcto de interpolación … Quiero algo como esto

tomado de canvasxpress.org/line.html

donde se alisa cada línea. Probé varias combinaciones de scipy y matplotlib, como

x_new = np.arange(x, x_length, 1) tck = interpolate.splrep(x, y, s=3) y_new = interpolate.splev(x_new, tck, der=0) ax.plot(x_new, y_new, color+lstyle) 

pero el mejor resultado que obtengo es

mi resultado

La línea representa una variable creciente … por lo que es una representación incorrecta. ¿Qué puedo buscar?

Gracias

Edit: Estoy pensando en implementar un método por mi cuenta, pero no sé si ya se ha hecho … el pseudo código es el siguiente

 take x and y calculate spline for each three points x[0], x[1], x[2] ... x[1], x[2], x[3] ... and so on for each y[n] sums every computation done for it and divide by number of computations (ie y[1] is computed for triplette x[0..2] and x[1..3] so the sum is divided by two (average for each point is taken as its value) 

Para ese tipo de gráfico, quieres interpolación monotónica . Se puede PchipInterpolator clase PchipInterpolator (a la que puede hacer referencia por su alias más corto pchip ) en scipy.interpolate:

 import numpy as np from scipy.interpolate import pchip import matplotlib.pyplot as plt # Data to be interpolated. x = np.arange(10.0) y = np.array([5.0, 10.0, 20.0, 15.0, 13.0, 22.0, 20.0, 15.0, 12.0, 16.0]) # Create the interpolator. interp = pchip(x, y) # Dense x for the smooth curve. xx = np.linspace(0, 9.0, 101) # Plot it all. plt.plot(xx, interp(xx)) plt.plot(x, y, 'bo') plt.ylim(0, 25) plt.grid(True) plt.show() 

Resultado:

introduzca la descripción de la imagen aquí

El problema no es un problema de visualización. Es un problema de interpolación. Estás interpolando usando funciones spline. Elegir el método de interpolación correcto depende en gran medida del tipo de datos que tenga. No puede esperar tener una función de interpolación que se comporte correctamente en todas las circunstancias (la interpolación no tiene forma de saber que su función está aumentando).

O bien deberías mirar

scipy.interpolate.LSQUnivariateSpline y jugar con el parámetro k (grado de la spline)

o scipy.interpolate.UnivariateSpline y jugar con los parámetros k y s.

Es importante comprender que la interpolación no es solo una línea para la visualización. Es un modelo matemático que representa cómo cree que se comporta el sistema (el sistema que genera los datos que midió). Diferentes tipos de interpolaciones representan diferentes suposiciones sobre el sistema.

Entonces, si sabe que su sistema es tal que una variable solo puede boost, debe ajustar un modelo apropiado (es decir, usar la interpolación apropiada). En cuanto a sus datos, parece que un polinomio de segundo grado o una función exponencial podrían encajar bien. Un ajuste de Loess (regresión local) también funcionará. Puede usar funciones personalizadas como numpy.polyfit () o ajuste de curva genérico con scipy.optimize.curve_fit (). Si tiene más conocimiento sobre el sistema, debe usarlo para seleccionar el modelo que se ajusta.

He mirado alrededor un poco. Lo que quieras se llama

Interpolación cúbica monótona,

Ver Wikipedia aquí . Usted tiene una discusión sobre el intercambio de matemáticas al respecto aquí y he encontrado una implementación en Python aquí . ¡Hazme saber si esto funciona!