从matplotlib

问题描述

我有2个带有数据的numpy数组,例如x,y,然后应用plt.step()并得到它的连续(步进)曲线。

我希望能够自己创建此函数,这意味着我想对y的{​​{1}}值(实际上不存在)进行(零阶保持)步长近似在原始x数组中。

例如,在下面的链接中,我想拥有“新”实际矩形正弦值,而不仅仅是绘制: https://matplotlib.org/gallery/lines_bars_and_markers/step_demo.html#sphx-glr-gallery-lines-bars-and-markers-step-demo-py

解决方法

您可以使用scipy的interp1d创建步进功能。默认情况下,插值是“线性”的,但是对于阶跃函数,您可以将其更改为“下一个”,“上一个”或“最近”。

step_fun = interp1d(x,y,kind='previous')获得标准步进函数,然后将其称为step_fun(new_x)

以下代码比较了不同类型的“插值”:

from matplotlib import pyplot as plt
import numpy as np
from scipy.interpolate import interp1d

x = np.random.uniform(0.1,0.7,20).cumsum()
y = np.sin(x)

kinds = ['linear','previous','next','nearest','cubic']
for i,kind in enumerate(kinds):
    function_from_points = interp1d(x,y + i,kind=kind)
    x_detailed = np.linspace(x[0],x[-1],1000)
    plt.plot(x_detailed,function_from_points(x_detailed),color='dodgerblue')
    plt.scatter(x,color='crimson')
plt.yticks(range(len(kinds)),kinds)
plt.show()

example plot

,

您可以选择刻度值和相应的函数值。这是一个不等距的参数及其值的示例:

x = np.arange(20) + np.random.random(20)/2
y = np.sin(x / 2)**2 + np.random.random(20)/5

备注:这两个数组的大小必须相等。如果要使用自己的自定义函数,可以使用np.vectorise

x = np.arange(20) + np.random.random(20)/2
func = np.vectorize(lambda x: np.sin(x) + np.random.random()/5)
y = func(x)