【问题标题】: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;
}
}
【解决方案5】:
也许有人会遇到同样的问题并且需要它...我需要非常快速的绘图来显示来自示波器的数据。
我正在以数据包的形式获取数据。我做了一些更改,使代码很多更快。
首先是将函数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
主函数中的代码会更长,但函数会更快,因为您“一次”添加所有数据。