【问题标题】:How can I make "real-time" plots with wxMathPlot?如何使用 wxMathPlot 制作“实时”绘图?
【发布时间】:2010-11-02 15:41:15
【问题描述】:

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

I.E.我不想要一个一次性读取文件的静态图 - 我想要绘制流数据并继续到图的右侧 - (让左侧脱落/滚动出视图)

编辑

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

【问题讨论】:

    标签: c++ wxwidgets plot graphing wxmathplot


    【解决方案1】:

    感谢乌鸦点...!!我做了你说的......它完美无瑕! 这是我的 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();
    

    【讨论】:

      【解决方案2】:

      我认为 mpFXYVector 是要走的路。

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

      更优雅的方法是使用 mpFXYVector 中的简单向量实现 FIFO 缓冲区的 mpFXYVector 的专门化。这样做的好处是您只持有一份显示数据的副本。除非您要显示数千个点,否则我怀疑从 mpFXYVector 继承而不是简单地使用 mpFXYVector 文档化接口的优势值得付出额外的麻烦。

      查看细节后,唯一棘手的一点是用新方法 Add() 替换 mpFXYVector::SetData() 以在数据点到达时添加数据点。新方法需要将 mpFXYVector 向量作为 FIFO 缓冲区进行管理,并重新实现代码以更新边界框(不幸的是,在编写时没有考虑到继承)。

      结果是,与使用包装器相比,专业化提供了一种内存需求更小、灵活性更高的解决方案。

      【讨论】:

      • 谢谢詹姆斯 - 这是一个很大的帮助。
      【解决方案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;
          }
      }
      

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          也许有人会遇到同样的问题并且需要它...我需要非常快速的绘图来显示来自示波器的数据。 我正在以数据包的形式获取数据。我做了一些更改,使代码很多更快。 首先是将函数SetData 中的if 状态从if (xs.size()&gt;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
          

          主函数中的代码会更长,但函数会更快,因为您“一次”添加所有数据。

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-06-20
              • 1970-01-01
              • 2013-01-05
              • 1970-01-01
              • 1970-01-01
              • 2023-02-09
              • 1970-01-01
              相关资源
              最近更新 更多