如何使用wxMathPlot创建“实时”图?

时间:2009-06-13 02:54:39

标签: c++ wxwidgets plot graphing wxmathplot

我正在考虑使用wxMathPlot绘制/绘制一些连续到达的数据。我想用它绘制“实时”情节/图表。这可能吗?

即。我不想只是一次性读取文件的静态图 - 我希望绘制流数据并继续到图的右侧 - (并让左侧掉落/滚出视图)< / p>

修改

我还没有得到答案。 wxmathPlot库中有一个名为mpFXYVector的有趣类,但它只是从数据向量中绘制一个图。我想要的是可以输入流并水平滚动图形的东西(如果需要也可以调整比例)

6 个答案:

答案 0 :(得分:5)

谢谢ravenspoint ...... !!我做了你说的..它完美无瑕! 这是我的AddData()函数:

void mpFXYVector::AddData(float x, float y, std::vector<double> &xs, std::vector<double> &ys)
    {
        // Check if the data vectora are of the same size
        if (xs.size() != ys.size()) {
            wxLogError(_("wxMathPlot error: X and Y vector are not of the same length!"));
            return;
        }

        //Delete first point if you need a filo buffer (i dont need it)
        //xs.erase(xs.begin());
        //xy.erase(xy.begin());

        //Add new Data points at the end
        xs.push_back(x);
        ys.push_back(y);


        // Copy the data:
        m_xs = xs;
        m_ys = ys;

        // Update internal variables for the bounding box.
        if (xs.size()>0)
        {
            m_minX  = xs[0];
            m_maxX  = xs[0];
            m_minY  = ys[0];
            m_maxY  = ys[0];

            std::vector<double>::const_iterator  it;

            for (it=xs.begin();it!=xs.end();it++)
            {
                if (*it<m_minX) m_minX=*it;
                if (*it>m_maxX) m_maxX=*it;
            }
            for (it=ys.begin();it!=ys.end();it++)
            {
                if (*it<m_minY) m_minY=*it;
                if (*it>m_maxY) m_maxY=*it;
            }
            m_minX-=0.5f;
            m_minY-=0.5f;
            m_maxX+=0.5f;
            m_maxY+=0.5f;
        }
        else
        {
            m_minX  = -1;
            m_maxX  = 1;
            m_minY  = -1;
            m_maxY  = 1;
        }
    }
在Main()中你只需要:

m_Vector->AddData(xPos,yPos,vectorX, vectorY);
m_plot->Fit();

答案 1 :(得分:3)

我认为mpFXYVector是要走的路。

处理这个问题的最简单方法可能是为mpFXYVector编写一个包装类,它包含最近数据点的FIFO缓冲区。每次新的数据点到达时,将其添加到FIFO缓冲区,这将删除最旧的点,然后使用更新的缓冲区加载mpFXYVector。 wxMathPlot类mpWindow将负责您所需的其余部分。

更优雅的方法是mpFXYVector的特化,它使用mpFXYVector中的简单向量实现FIFO缓冲区。这样做的好处是您只能保留一份显示数据。除非你显示了数千个点,否则我怀疑从mpFXYVector继承的额外麻烦,而不是简单地使用mpFXYVector记录的界面。

在查看详细信息之后,唯一棘手的问题是用新方法Add()替换mpFXYVector :: SetData()以在数据点到达时添加它们。新方法需要将mpFXYVector向量作为FIFO缓冲区进行管理,并重新实现代码以更新边界框(遗憾的是,这不是用继承编写的)。

结果是,专业化提供的解决方案比使用包装器具有更小的内存要求和更大的灵活性。

答案 2 :(得分:3)

我知道这是一个旧线程,但我需要使用wxMathPlot绘制滚动X轴。

我对jayjo的代码做了一个简单的修改,使X轴滚动工作。

我帮忙。

void mpFXYVector::AddData(float x, float y, std::vector<double> &xs, std::vector<double> &ys)
{
    // Check if the data vectora are of the same size
    if (xs.size() != ys.size()) {
        wxLogError(_("wxMathPlot error: X and Y vector are not of the same length!"));
        return;
    }

    //After a certain number of points implement a FIFO buffer
    //As plotting too many points can cause missing data
    if (x > 300)
    {
        xs.erase(xs.begin());
        ys.erase(ys.begin());
    }



    //Add new Data points at the end
    xs.push_back(x);
    ys.push_back(y);


    // Copy the data:
    m_xs = xs;
    m_ys = ys;

    // Update internal variables for the bounding box.
    if (xs.size()>0)
    {
        m_minX  = xs[0];
        m_maxX  = xs[0];
        m_minY  = ys[0];
        m_maxY  = ys[0];

        std::vector<double>::const_iterator  it;

        for (it=xs.begin();it!=xs.end();it++)
        {
            if (*it<m_minX) m_minX=*it;
            if (*it>m_maxX) m_maxX=*it;
        }
        for (it=ys.begin();it!=ys.end();it++)
        {
            if (*it<m_minY) m_minY=*it;
            if (*it>m_maxY) m_maxY=*it;
        }
        m_minX-=0.5f;
        m_minY-=0.5f;
        m_maxX+=0.5f;
        m_maxY+=0.5f;
    }
    else
    {
        m_minX  = -1;
        m_maxX  = 1;
        m_minY  = -1;
        m_maxY  = 1;
    }
}

答案 3 :(得分:2)

我对wxMathPlot没有任何个人经验,但我一直在使用wxWidgets多年,并强烈推荐它用于c ++中的跨平台gui编程,根据wxWiki graphics page {{3} }可以用于实时数据,所以也许可以帮助你。祝你好运。

答案 4 :(得分:2)

也许有人会遇到同样的问题并需要它...我需要非常快速的绘图来显示示波器的数据。 我正在获取数据包中的数据。我做了一些更改,使代码更多更快。 首先是将函数SetData中的if状态从if (xs.size()>0)更改为if (!xs.empty)。 然后,您应该首先将所有数据包添加到向量

Vector1_X.push_back(x);
Vector1_Y.push_back(y);

之后你应该适合并设置数据。

Vector1 ->SetData(Vector1_X,Vector1_Y); // add vectors to main vector
MathPlot1-> Fit(); //fit plot to the data
Vector1_X.clear(); //if you want to clear plot after every packet 
Vector1_Y.clear(); //you should use it

主函数中的代码会更长,但功能会更快,因为您一次添加所有数据&#34;&#34;。

答案 5 :(得分:1)

我们最终使用了ChartDirector。它具有很多功能并且速度很快。

相关问题