4 Stimmen

Wie kann ich "Echtzeit" -Diagramme mit wxMathPlot erstellen?

Ich denke daran, wxMathPlot zu verwenden, um einige kontinuierlich eintreffende Daten zu plotten. Ich möchte damit ein "Echtzeit"-Diagramm erstellen. Ist das möglich?

Ich möchte nicht nur ein statisches Diagramm von einer einmaligen Dateilese haben - ich möchte die Daten im Stream plotten und sie weiterhin auf der rechten Seite des Diagramms fortsetzen lassen (und die linke Seite aus dem Blickfeld herausfallen/scrollen lassen).

BEARBEITEN

Ich habe immer noch keine Antwort darauf bekommen. In der wxmathPlot-Bibliothek gibt es eine interessante Klasse namens mpFXYVector, aber anscheinend zeichnet sie nur ein Diagramm aus einem Vektor von Daten. Ich möchte etwas, das einen Strom erhalten und das Diagramm horizontal scrollen lassen kann (und auch die Skalierung bei Bedarf anpassen)

5voto

jayjo Punkte 51

Danke ravenspoint...!! Ich habe gemacht, was du gesagt hast.. Es funktioniert einwandfrei! hier ist meine AddData() Funktion:

void mpFXYVector::AddData(float x, float y, std::vector &xs, std::vector &ys)
    {
        // Überprüfen, ob die Datenvektoren die gleiche Größe haben
        if (xs.size() != ys.size()) {
            wxLogError(_("wxMathPlot Fehler: X- und Y-Vektor haben nicht die gleiche Länge!"));
            return;
        }

        // Ersten Punkt löschen, wenn ein Filo-Buffer benötigt wird (ich brauche ihn nicht)
        //xs.erase(xs.begin());
        //xy.erase(xy.begin());

        // Neue Datenpunkte am Ende hinzufügen
        xs.push_back(x);
        ys.push_back(y);

        // Daten kopieren:
        m_xs = xs;
        m_ys = ys;

        // Interne Variablen für den Begrenzungsrahmen aktualisieren.
        if (xs.size()>0)
        {
            m_minX  = xs[0];
            m_maxX  = xs[0];
            m_minY  = ys[0];
            m_maxY  = ys[0];

            std::vector::const_iterator  it;

            for (it=xs.begin();it!=xs.end();it++)
            {
                if (*itm_maxX) m_maxX=*it;
            }
            for (it=ys.begin();it!=ys.end();it++)
            {
                if (*itm_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;
        }
    }

im Main() müssen Sie nur noch:

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

4voto

ravenspoint Punkte 16577

Ich denke, mpFXYVector ist der richtige Weg.

Der einfachste Weg, damit umzugehen, könnte sein, eine Wrapper-Klasse für mpFXYVector zu schreiben, die einen FIFO-Puffer für die neuesten Datenpunkte enthält. Jedes Mal, wenn ein neuer Datenpunkt eintrifft, fügen Sie ihn dem FIFO-Puffer hinzu, wodurch der älteste Punkt gelöscht wird, und laden Sie dann mpFXYVector mit dem aktualisierten Puffer. Die wxMathPlot-Klasse mpWindow kümmert sich um den Rest dessen, was Sie benötigen.

Ein eleganterer Ansatz wäre eine Spezialisierung von mpFXYVector, die den FIFO-Puffer implementiert, unter Verwendung der einfachen Vektoren in mpFXYVector. Der Vorteil dabei ist, dass Sie nur eine Kopie der Anzeigedaten behalten. Es sei denn, Sie zeigen viele Tausend Punkte an, bezweifle ich, dass der Vorteil den zusätzlichen Aufwand rechtfertigt, von mpFXYVector abzuleiten, anstatt einfach die dokumentierte Schnittstelle von mpFXYVector zu verwenden.

Nachdem Sie die Details betrachtet haben, ist das einzige knifflige Stück, mpFXYVector::SetData() durch eine neue Methode Add() zu ersetzen, um Datenpunkte hinzuzufügen, wenn sie eintreffen. Die neue Methode muss die mpFXYVector-Vektoren als FIFO-Puffer verwalten und den Code zur Aktualisierung der Begrenzungsbox neu implementieren (der leider nicht mit Vererbung im Sinn geschrieben wurde).

Das Ergebnis ist, dass die Spezialisierung eine Lösung mit einem geringeren Speicherbedarf und mehr Flexibilität bietet als die Verwendung einer Wrapper-Klasse.

3voto

JSU Punkte 106

Ich weiß, dass dies ein alter Thread ist, aber ich musste eine scrollbare X-Achse mit wxMathPlot darstellen.

Ich habe eine einfache Änderung an jayjos Code vorgenommen, damit das Scrollen der X-Achse funktioniert.

Ich hoffe, das hilft.

void mpFXYVector::AddData(float x, float y, std::vector &xs, std::vector &ys)
{
    // Überprüfen, ob die Datenvektoren die gleiche Größe haben
    if (xs.size() != ys.size()) {
        wxLogError(_("wxMathPlot Fehler: X- und Y-Vektoren haben nicht die gleiche Länge!"));
        return;
    }

    // Nach einer bestimmten Anzahl von Punkten implementieren Sie einen FIFO-Puffer
    // Da das Plotten von zu vielen Punkten dazu führen kann, dass Daten fehlen
    if (x > 300)
    {
        xs.erase(xs.begin());
        ys.erase(ys.begin());
    }

    // Neue Datenpunkte am Ende hinzufügen
    xs.push_back(x);
    ys.push_back(y);

    // Daten kopieren
    m_xs = xs;
    m_ys = ys;

    // Interne Variablen für die Bounding Box aktualisieren.
    if (xs.size()>0)
    {
        m_minX  = xs[0];
        m_maxX  = xs[0];
        m_minY  = ys[0];
        m_maxY  = ys[0];

        std::vector::const_iterator  it;

        for (it=xs.begin();it!=xs.end();it++)
        {
            if (*itm_maxX) m_maxX=*it;
        }
        for (it=ys.begin();it!=ys.end();it++)
        {
            if (*itm_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;
    }
}

2voto

snctln Punkte 12105

Ich habe keine persönliche Erfahrung mit wxMathPlot, aber ich arbeite seit Jahren mit wxWidgets und empfehle es sehr für die plattformübergreifende GUI-Programmierung in C++. Laut der wxWiki-Grafikseite kann die Numerix Graphics Library für Echtzeitdaten verwendet werden, also vielleicht kann dir das helfen. Viel Glück.

2voto

Vielleicht hat jemand das gleiche Problem und wird es brauchen... Ich brauchte sehr schnelles Zeichnen, um die Daten vom Oszilloskop anzuzeigen. Ich erhielt die Daten in Paketen. Ich habe ein paar Änderungen vorgenommen, die den Code viel schneller machten. Erste Sache ist, den if-Status in der Funktion SetData von if (xs.size()>0) in if (!xs.empty) zu ändern. Dann sollten Sie alle Ihre Datapakete zuerst zum Vektor hinzufügen

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

Und danach sollten Sie die Daten einpassen und setzen.

Vector1 ->SetData(Vector1_X,Vector1_Y); // Vektoren zum Hauptvektor hinzufügen
MathPlot1-> Fit(); // Diagramm an die Daten anpassen
Vector1_X.clear(); // wenn Sie das Diagramm nach jedem Paket löschen möchten
Vector1_Y.clear(); // sollten Sie es benutzen

Ihr Code in der Hauptfunktion wird länger sein, aber die Funktion wird schneller sein, da Sie alle Daten "auf einmal" hinzufügen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X