You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ScottPlot 5在.NET 8 WPF中绘制无峰值折线的问题求助

解决ScottPlot 5折线图峰值问题的两种方法

针对你在.NET 8 WPF项目中用ScottPlot 5绘制折线图出现明显高低峰值的问题,提供两种可行的解决思路:

一、数据预处理:滑动平均消除峰值

最直接的方式是对原始数据做平滑处理,**滑动平均(移动平均)**是常用的消除突变峰值的方法,通过计算相邻N个数据点的平均值来削弱极端值的影响。

实现代码

先添加一个滑动平均的工具方法:

private double[] MovingAverage(double[] data, int windowSize)
{
    if (windowSize < 2 || data.Length < windowSize)
        return data;

    double[] smoothed = new double[data.Length];
    for (int i = 0; i < data.Length; i++)
    {
        int start = Math.Max(0, i - windowSize / 2);
        int end = Math.Min(data.Length - 1, i + windowSize / 2);
        double sum = 0;
        int count = 0;
        for (int j = start; j <= end; j++)
        {
            sum += data[j];
            count++;
        }
        smoothed[i] = sum / count;
    }
    return smoothed;
}

然后修改你的Test方法,用处理后的数据绘图:

private void Test()
{
    var plt = WpfPlot1.Plot;
    plt.Clear(); // 先清除原有绘图

    var lines = File.ReadAllLines("./files/result.csv").Skip(1);
    // 适配CSV中的逗号小数分隔符,指定正确的文化信息
    var dates = lines.Select(line => DateTime.ParseExact(line.Split(';')[0], "yyyy-MM-dd", CultureInfo.InvariantCulture)).ToArray();
    var closes = lines.Select(line => double.Parse(line.Split(';')[1], new CultureInfo("fr-FR"))).ToArray();

    // 用窗口大小为3的滑动平均处理数据(可根据需求调整windowSize)
    var smoothedCloses = MovingAverage(closes, 3);

    DateTime start = dates.First();
    var sig = plt.Add.Signal(smoothedCloses);
    sig.Data.XOffset = start.ToOADate();
    sig.Data.Period = 1.0;

    plt.Axes.DateTimeTicksBottom();
    WpfPlot1.Refresh();
}

说明:windowSize越大,平滑效果越明显,但会损失数据细节,你可以根据需求调整参数(比如3、5、7)。

二、使用ScottPlot内置的平滑折线功能

ScottPlot 5支持直接绘制平滑折线,无需手动处理数据,适合希望保留原始数据趋势但让折线视觉上更连贯的场景。

修改后的代码

把Add.Signal替换为Add.SmoothLine,并可调整平滑度:

private void Test()
{
    var plt = WpfPlot1.Plot;
    plt.Clear();

    var lines = File.ReadAllLines("./files/result.csv").Skip(1);
    var dates = lines.Select(line => DateTime.ParseExact(line.Split(';')[0], "yyyy-MM-dd", CultureInfo.InvariantCulture)).ToArray();
    var closes = lines.Select(line => double.Parse(line.Split(';')[1], new CultureInfo("fr-FR"))).ToArray();

    // 转换为X-Y数据对,使用SmoothLine绘制
    var xVals = dates.Select(d => d.ToOADate()).ToArray();
    var smoothLine = plt.Add.SmoothLine(xVals, closes);
    // 调整平滑度:SmoothFactor越大越平滑,范围0-1(默认0.5)
    smoothLine.SmoothFactor = 0.7;

    plt.Axes.DateTimeTicksBottom();
    WpfPlot1.Refresh();
}

说明:SmoothFactor参数控制平滑程度,0为完全不平滑(原始折线),1为最大平滑效果。这种方法不会修改原始数据,仅通过插值优化折线视觉效果。

额外提示

你当前的double.Parse存在潜在风险:CSV中的小数用逗号(1,10588),默认解析逻辑会依赖系统文化信息,若系统为英文环境会直接报错。务必指定支持逗号小数的文化信息(如fr-FR、de-DE),避免运行时错误。


内容的提问来源于stack exchange,提问作者Blazer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 18:07:47