Как я могу создавать графики в режиме реального времени с помощью wxMathPlot? - PullRequest
3 голосов
/ 13 июня 2009

Я думаю об использовании wxMathPlot для построения графиков / графиков некоторых данных, которые поступают непрерывно. Я хочу нарисовать график в реальном времени, используя его. Это возможно?

т.е. Я не хочу просто статический график одноразового чтения файла - я хочу, чтобы потоковые данные отображались и продолжались справа от графика - (и позволяли левой стороне падать / прокручиваться вне поля зрения) 1005 *

EDIT

Я до сих пор не получил ответа на это. В библиотеке wxmathPlot есть интересный класс, называемый mpFXYVector, но он создается только для рисования одного графика из вектора данных. То, что я хочу, это то, что можно подавать поток и прокручивать график по горизонтали (а также изменять размер шкалы при необходимости)

Ответы [ 6 ]

5 голосов
/ 07 октября 2010

Спасибо 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();
3 голосов
/ 04 июня 2013

Я знаю, что это старая нить, но мне нужно было построить ось прокрутки X с помощью wxMathPlot.

Я сделал простое изменение в коде 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 голосов
/ 19 октября 2009

Я думаю, что mpFXYVector - это путь.

Простейшим способом решения этой проблемы может быть написание класса-оболочки для mpFXYVector, который содержит буфер FIFO последних точек данных. Каждый раз, когда приходит новый объект данных, добавляйте его в буфер FIFO, который отбросит самую старую точку, а затем загрузите mpFXYVector с обновленным буфером. Класс wxMathPlot mpWindow позаботится обо всем, что вам нужно.

Более элегантный подход - это специализация mpFXYVector, которая реализует буфер FIFO, используя простые векторы в mpFXYVector. Преимущество этого состоит в том, что вы держите только одну копию отображаемых данных. Если вы не отображаете много тысяч точек, я сомневаюсь, что преимущество стоит дополнительной проблемы наследования от mpFXYVector, а не просто использования документированного интерфейса mpFXYVector.

После изучения деталей, единственный хитрый момент - заменить mpFXYVector :: SetData () новым методом Add () для добавления точек данных по мере их поступления. Новый метод должен управлять векторами mpFXYVector как буферами FIFO и повторно реализовывать код для обновления ограничивающего прямоугольника (который, к сожалению, не был написан с учетом наследования).

В результате специализация дает решение с меньшими требованиями к памяти и большей гибкостью, чем при использовании оболочки.

2 голосов
/ 30 ноября 2015

Может быть, у кого-то будет такая же проблема, и она понадобится ... Мне нужно было очень быстрое построение графика для отображения данных с осциллографа. Я получал данные в пакетах. Я сделал несколько изменений, которые сделали код намного быстрее. Прежде всего, нужно изменить состояние if в функции SetData с 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

Ваш код в основной функции будет длиннее, но функция будет быстрее, потому что вы добавляете все данные "сразу".

2 голосов
/ 13 июня 2009

У меня нет личного опыта работы с wxMathPlot, но я работаю с wxWidgets в течение многих лет и очень рекомендую его для кроссплатформенного программирования на графическом языке в c ++, при этом в соответствии с графической страницей wxWiki Графическая библиотека Numerix может использоваться для данных в реальном времени, так что, возможно, это поможет вам. Удачи.

1 голос
/ 07 октября 2010

В итоге мы взяли ChartDirector . У этого есть много возможностей и быстро.

...