使用 PyPlot 绘制平滑线

2025-01-08 08:49:00
admin
原创
93
摘要:问题描述:我有以下绘制图形的简单脚本: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+0...

问题描述:

我有以下绘制图形的简单脚本:

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

现在,线条从点到点笔直延伸,看起来还不错,但我认为可以做得更好。我想要的是平滑点之间的线条。在 Gnuplot 中,我会用 进行绘图smooth cplines

在 PyPlot 中是否有简单的方法可以做到这一点?我找到了一些教程,但它们看起来都很复杂。


解决方案 1:

您可以使用scipy.interpolate.spline自己来平滑数据:

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 在 scipy 0.19.0 中已弃用,请改用 BSpline 类。

从 切换splineBSpline并不是简单的复制/粘贴,需要进行一些调整:

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

前:
屏幕截图 1

后:
屏幕截图 2

解决方案 2:

对于这个例子,样条曲线效果很好,但如果函数本身不平滑,而你想要平滑的版本,你也可以尝试:

from scipy.ndimage.filters import gaussian_filter1d

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

如果增加 sigma,您可以获得更平滑的函数。

请谨慎操作。它会修改原始值,可能不是您想要的。

解决方案 3:

请参阅scipy.interpolate文档来了解一些示例。

下面的例子演示了它的用法,用于线性和三次样条插值:

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

# Define x, y, and xnew to resample at.
x = np.linspace(0, 10, num=11, endpoint=True)
y = np.cos(-x**2/9.0)
xnew = np.linspace(0, 10, num=41, endpoint=True)

# Define interpolators.
f_linear = interp1d(x, y)
f_cubic = interp1d(x, y, kind='cubic')

# Plot.
plt.plot(x, y, 'o', label='data')
plt.plot(xnew, f_linear(xnew), '-', label='linear')
plt.plot(xnew, f_cubic(xnew), '--', label='cubic')
plt.legend(loc='best')
plt.show()

在此处输入图片描述

稍作修改以增加可读性。

解决方案 4:

我发现最简单的实现之一是使用 Tensorboard 使用的指数移动平均线:

def smooth(scalars: List[float], weight: float) -> List[float]:  # Weight between 0 and 1
    last = scalars[0]  # First value in the plot (first timestep)
    smoothed = list()
    for point in scalars:
        smoothed_val = last * weight + (1 - weight) * point  # Calculate smoothed value
        smoothed.append(smoothed_val)                        # Save it
        last = smoothed_val                                  # Anchor the last smoothed value
        
    return smoothed


ax.plot(x_labels, smooth(train_data, .9), label="Train Smooth")  # label="Train") # uncomment to reproduce figure below
ax.plot(x_labels, train_data, label="Train")  # label="Train Smooth") # uncomment to reproduce figure below

在此处输入图片描述

解决方案 5:

以下是日期的简单解决方案:

from scipy.interpolate import make_interp_spline
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as dates
from datetime import datetime

data = {
    datetime(2016, 9, 26, 0, 0): 26060, datetime(2016, 9, 27, 0, 0): 23243,
    datetime(2016, 9, 28, 0, 0): 22534, datetime(2016, 9, 29, 0, 0): 22841,
    datetime(2016, 9, 30, 0, 0): 22441, datetime(2016, 10, 1, 0, 0): 23248 
}
#create data
date_np = np.array(list(data.keys()))
value_np = np.array(list(data.values()))
date_num = dates.date2num(date_np)
# smooth
date_num_smooth = np.linspace(date_num.min(), date_num.max(), 100) 
spl = make_interp_spline(date_num, value_np, k=3)
value_np_smooth = spl(date_num_smooth)
# print
plt.plot(date_np, value_np)
plt.plot(dates.num2date(date_num_smooth), value_np_smooth)
plt.show()

例子

解决方案 6:

从你问题的上下文来看,我猜你指的是曲线拟合而不是抗锯齿。PyPlot 没有内置支持,但你可以自己轻松实现一些基本的曲线拟合,比如这里看到的代码,或者如果你使用 GuiQwt,它有一个曲线拟合模块。(你也可以从SciPy窃取代码来做到这一点)。

解决方案 7:

值得你花时间研究一下seaborn如何绘制平滑的线条。

seaborn lmplot函数将绘制数据和回归模型拟合。

下面说明了多项式拟合和Lowess拟合:

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

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

df = pd.DataFrame(data = {'T': T, 'power': power})
    
sns.lmplot(x='T', y='power', data=df, ci=None, order=4, truncate=False)
sns.lmplot(x='T', y='power', data=df, ci=None, lowess=True, truncate=False)

在此处输入图片描述

多项式order = 4拟合过度拟合了这个小数据集。我没有在这里展示它,但order = 2结果order = 3更糟。

在此处输入图片描述

拟合lowess = True对于这个小数据集来说是欠拟合,但对于较大的数据集可能会产生更好的结果。

查看seaborn 回归教程以获取更多示例。

解决方案 8:

另一种方法是根据您使用的参数稍微修改函数:

from statsmodels.nonparametric.smoothers_lowess import lowess

def smoothing(x, y):
    lowess_frac = 0.15  # size of data (%) for estimation =~ smoothing window
    lowess_it = 0
    x_smooth = x
    y_smooth = lowess(y, x, is_sorted=False, frac=lowess_frac, it=lowess_it, return_sorted=False)
    return x_smooth, y_smooth

这比其他答案更适合我的具体应用案例。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用