QCustomPlot Discussion and Comments

Membership functionsReturn to overview

Hi there, first of all I want to let You that... QCustomPlot is going to save my life, literally !

Anyway, before to consider myself completely safe, I need just one more help: this time by the community.

I'm working on a simple tool, used to visualize fuzzy membership functions. Suppose you have something like this...

f(x) = 0 if x < a

f(x) = [(x - a) / (m - a)] if a < x <= m

f(x) = [(b - x) / (b - m)] if m < x < b

f(x) = 0 if x >= b

that describes the triangular membership function.

What I need to do is, given some values of a, x, m, b, to plot f(x).

Any suggestions on how to this ?

Thank you in advance.

Here is the source code.

void MainWindow::plotTriangulaMF(double x, double a, double b, double m, QCustomPlot *customPlot)
{
    double y;

        if (x <= a)
        { y = 0; }

        if ((x > a) && (x <= m))
        { y = ((x - a) / (m - a)); }

        if ((x > m) && (x < b))
        { y = ((b - x) / (b - m)); }

        if (x >=b )
        { y = 0; }

    customPlot->addGraph();

    customPlot->graph(0)->setData(x, y);

    customPlot->xAxis->setLabel("x");
    customPlot->yAxis->setLabel("y");

    customPlot->xAxis->setRange(0, 10);
    customPlot->yAxis->setRange(0, 1);
}

Of course x, and y should be of type

QVector<double>

and that's here I've got troubles.

You're only plotting a single data point. Try something like this:

    
int n = 500;
QVector<double> x(n), y(n);
double startx = a - 5.0;
double endx = b + 5.0;
for (int i=0; i<n; ++i)
{
  x[i] = startx+(endx-startx)/(double)(n-1)*i;
  if ((x[i] > a) && (x[i] <= m)) y[i] = ((x[i] - a) / (m - a));
  else if ((x[i] > m) && (x[i] < b)) y[i] = ((b - x[i]) / (b - m));
  else y[i] = 0;
}

customPlot->addGraph();
customPlot->graph()->setData(x, y);
customPlot->xAxis->setLabel("x");
customPlot->yAxis->setLabel("y");
customPlot->graph()->rescaleAxes();
customPlot->replot();

This code is not tested.
Note that since your piecewise functions are all linear, you could reduce the whole thing to just a few points at the intersections (where the transition to a different linear function occurs). However, I've chosen to sample the whole thing with 500 points, this way you could also define piecewise nonlinear functions and get good results.