How to plot function in fltk

1,305 views
Skip to first unread message

sabbir shubho

unread,
Mar 18, 2021, 5:31:25 PM3/18/21
to fltk.general
I am trying to plot two or more function like first order equation , unit function etc.. in single plot using fltk library. I have already seen the draw an X example but it did not help me much.

Appreciate any help on how to plot function in fltk

Sabbir Ahamed

Greg Ercolano

unread,
Mar 18, 2021, 5:59:55 PM3/18/21
to fltkg...@googlegroups.com

On 3/18/21 2:14 PM, sabbir shubho wrote:

I am trying to plot two or more function like first order equation , unit function etc.. in single plot using fltk library. I have already seen the draw an X example but it did not help me much.

Appreciate any help on how to plot function in fltk


    Plotting a graph is just drawing points between the samples of your function.
    The "draw an X" example should show you all the FLTK related code to do this.

    Just add the loop needed to iterate through the values of your function for each
    data point, and draw a line from the last point to the current point, scaling and
    translating the raw data from your function to integer screen coordinates within
    the x/y/w/h rectangle, as shown by the "draw an X" code.

    Is there something specific you're having trouble with doing?

Ian MacArthur

unread,
Mar 18, 2021, 6:09:01 PM3/18/21
to fltkg...@googlegroups.com
And indeed, if you just need to plot a function, gnu plot might be a better bet than writing your own graph plotter in fltk, I suppose...



Message has been deleted
Message has been deleted

sabbir shubho

unread,
Mar 18, 2021, 6:21:43 PM3/18/21
to fltk.general

I am trying to plot the sine wave function for example. In the loop, I save the value of the sine function in an array that is of type float. The draw x example shows how to draw a line between two points which are pixel value or absolute coordinate. I am looking to draw an axis on the screen and have my function plotted on the screen as normally we do in Matlab or python.
I am attaching a sample picture that I want to draw in fltk.
CombinePlotsTiledLayoutExample_01.png

Greg Ercolano

unread,
Mar 18, 2021, 10:01:17 PM3/18/21
to fltkg...@googlegroups.com

On 3/18/21 3:20 PM, sabbir shubho wrote:


I am trying to plot the sine wave function for example. In the loop, I save the value of the sine function in an array that is of type float. The draw x example shows how to draw a line between two points which are pixel value or absolute coordinate. I am looking to draw an axis on the screen and have my function plotted on the screen as normally we do in Matlab or python.
I am attaching a sample picture that I want to draw in fltk.



FLTK is a simple graphics toolkit providing bare bones drawing stuff, and doesn't often have high level tools like math plotting.

That said, there is a widget called Fl_Chart that can plot bargraphs and line graphs, but it's very rudimentary. I don't think FLTK has a good example showing its various uses.. it could use one. From what I can find, it supports at least these types of graphs.. not sure where the example code that made this screenshot though:
Fl_ChartAsking for some help about
          Charts - freebasic.net

If I can find some time, I'll try to provide a variations of my cheat sheet's Fl_Graph example that shows how plot line graphs for data, too. It might be as easy as just changing Fl_Graph::type().

Short of that, you'd either have to draw all that yourself (the graticule markings, labels, text heading), or use a third party FLTK library that provides such high level graphing features.. just googling around, there seems to be Fl_ChartEx, Multiplot, ..and I imagine there's several others.

I think most people would simply do it themselves, as it's not that hard to draw lines and text in FLTK. And now that FLTK supports SVG, one should be able to plot really nice looking stuff with antialiased lines, filled gradients, and whatnot. Getting text mixed with SVG might be a little tricky though. An interesting FLTK widget to see would be Fl_Chart refitted to use SVG that handles all that.

I'd wait to see other folk's replies though, as there may be things I'm not aware of.. in my work I don't often find the need to graph things.


Bill Spitzak

unread,
Mar 18, 2021, 10:09:09 PM3/18/21
to fltkg...@googlegroups.com
Fl_Chart is mostly there because the Forms library had it. Once upon a time you were able to compile Forms programs with no changes and they would work in FLTK.

I agree that just directly drawing things is best.


--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkgeneral/06bbdc20-71f7-0216-9f52-2c1bd4e116c2%40seriss.com.

Greg Ercolano

unread,
Mar 18, 2021, 11:14:28 PM3/18/21
to fltkg...@googlegroups.com
That said, there is a widget called Fl_Chart that can plot bargraphs and line graphs, but it's very rudimentary. I don't think FLTK has a good example showing its various uses.. it could use one.

[..]


If I can find some time, I'll try to provide a variations of my cheat sheet's Fl_Graph example that shows how plot line graphs for data, too. It might be as easy as just changing Fl_Graph::type().

    I just now added examples/chart-simple.cxx to demonstrate Fl_Chart's different chart styles.

    It's basically my old cheat sheet example with a chooser added to change the chart type, with FL_LINE_CHART being one of the many visualization options:



As I said, pretty rudimentary; you'll surely want to draw your own, especially if you want an axis labels, tick marks, grids, legends, self-avoiding text, etc.

But sniff around on the web; I know there's math folks who've made FLTK graphing/plotting library tools.

I just went on the fltk.org "Links" page under the "Software -> Programming Tools" subsection, and found a few more plotting tools. Have to warn you, because it's so old, there's many links there that have long gone stale. In those days there weren't long term dumping grounds like github, and sourceforge was still new then. So if you see something that you like but the link is dead, try archive.org and sometimes you can find a tar ball.

For links that are still alive, here's one called OctPlot:


..and here's one called "Gluplot", which describes itself as a clone of the "Gnuplot" tool, but is a library too:

There are probably many others folks have written, try searching the forums for "graphing" and "plotting".

Rob McDonald

unread,
Mar 19, 2021, 1:21:15 AM3/19/21
to fltk.general
I have used Roman Kantor's Cartesian library.

It appears abandoned, you can find occasional references to it on the internet.  While based on ancient FLTK, it still pretty much just works.

The version embedded in my project is probably as good a source as any (I can't find any download maintained by the original author).  We've made some occasional improvements / fixes, but mostly it works for simple charts.


Rob

geert karman

unread,
Mar 19, 2021, 3:17:29 AM3/19/21
to fltk.general
I have used Roman Kantor's Cartesian library.

I started off (years ago) with the Cartesian library, but needed some of my own special stuff and found it hard to integrate it there (one of the new features is a possibility to zoom in). Inspired by It, I ended up rewriting my own from scratch. I happen to have taken it up again not long ago and am right in the middle of turning it into a library. Still work to do but it almost meets my own needs now. Screenshot attached. Anyone interested, drop me a note.

 graphs.jpg

Claude Roux

unread,
Mar 19, 2021, 3:26:27 AM3/19/21
to fltk.general
I have implemented a method that takes a list of points, calcules the landmarks in order to get all these points in the same plan.

The function starts at line: 794...

It expects either a vector of x,y points (see line 841) or an even lists of values, which then will be interpreted as x,y coordinates (see line 881)

 It is part of a programming language that I have implemented...

Some explanations:
A List object is a vector, which contains Element objects, that can be read as double through the asNumber method.
Basically points is a vector<double>
storevalue pushes a double into a vector<double>. This is used to save the values of the landmark in kvect...

What plot does is to compute the minimum and the maximum of your list of points then compute against the dimensions of your window how to plot each of them.
You can either connect each point with lines (see line 930) or as little circle (see line 941)

sabbir shubho

unread,
Mar 31, 2021, 10:29:22 AM3/31/21
to fltkg...@googlegroups.com
Hello,
I implemented for plotting the graph and I am attaching the code and output image here, but still facing some issues. 
Can you help me with how to add axis and scale in that graph?

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/fl_draw.H>

#include <math.h>
#include <time.h>

#define GRAPH_MAX 101
#define T 0.1 // Sampling time

struct GRAPH
{
double x[GRAPH_MAX+1];
double x1[GRAPH_MAX+1];
double x2[GRAPH_MAX+1];

int n;
};

static struct GRAPH Graph;

class GRAPHBOX : public Fl_Box
{
    void draw()
{
// redraw background

Fl_Box::draw();

fl_color(fl_rgb_color(0, 0, 0));
fl_line(x(), y()+h()/2, x()+w(), y()+h()/2);
fl_line(x(), y(), x(), y()+h());

// redraw graph
// sine function
int n;
for (n=0; n<Graph.n; n++)
{
int xk = x() + 5*(n + 1);
int yk = y() + h()/2 - 100*Graph.x[n];

fl_color(fl_rgb_color(127, 0, 0));
fl_begin_polygon();
fl_arc(xk, yk, 2, 0, 360);

fl_end_polygon();

fl_color(fl_rgb_color(0, 0, 0));
fl_begin_line();
fl_circle(xk, yk, 2);
fl_end_line();
}
// equation
int p;
for (p=0; p<Graph.n; p++)
{
int xk = x() + 5*(p + 1);
int yk = y() + h()/2 - 100*Graph.x1[p];

fl_color(fl_rgb_color(0, 127, 0));
fl_begin_polygon();
fl_arc(xk, yk, 2, 0, 360);

fl_end_polygon();

fl_color(fl_rgb_color(0, 0, 0));
fl_begin_line();
fl_circle(xk, yk, 2);
fl_end_line();
}

fl_font(FL_COURIER, 16);
char str[256],str1[256];
n = Graph.n-1;
sprintf(str, "sin(%2d)=% 1.4lf", n, Graph.x[n]);
sprintf(str1, "x(%2d)=% 1.4lf", n, Graph.x1[n]);
fl_color(fl_rgb_color(127, 0, 0));
fl_draw(str, x()+w()/2, y()+h()-20);
fl_color(fl_rgb_color(0, 127, 0));
fl_draw(str1, x()+w()/2, y()+h()-40);
    }

public:
GRAPHBOX(int x, int y, int w, int h, const char *l=0) : Fl_Box(x, y, w, h, l)
{
box(FL_FLAT_BOX);
color(fl_rgb_color(127, 127, 127));
    }
};

static bool RUNNING = true;

static void WAIT(double time)
{
int cnt = clock();
int ticks = (int) (time*CLOCKS_PER_SEC);
while (true)
{
if (clock() > (cnt + ticks))
return;
else
{
// workaround for Fl::wait(0.0) which does not return RUNNING
RUNNING = Fl::check();
}
}
}

int main(void)
{
Fl_Window window(550, 400, "Graph");
GRAPHBOX graphbox(10, 10, window.w()-20, window.h()-20);
window.show();

Graph.x1[0] = 0.0;
Graph.x2[0] = 0.0;

Graph.n = 0;

while (RUNNING)
{
if (Graph.n < GRAPH_MAX)
{
Graph.x[Graph.n] = sin(2* Graph.n * T);
Graph.x1[Graph.n+1] = Graph.x1[Graph.n]+ T* Graph.x2[Graph.n];
Graph.x2[Graph.n+1] = Graph.x2[Graph.n]- T* (Graph.x1[Graph.n+1]+2*Graph.x2[Graph.n])+ T* Graph.x[Graph.n];
Graph.n++;
graphbox.redraw();
WAIT(0.05);
}
else
{
// done graph
RUNNING = Fl::wait();
}
}
return EXIT_SUCCESS;
}

--
You received this message because you are subscribed to the Google Groups "fltk.general" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkgeneral...@googlegroups.com.
plot.PNG

Greg Ercolano

unread,
Mar 31, 2021, 12:10:44 PM3/31/21
to fltkg...@googlegroups.com


On 3/31/21 7:17 AM, sabbir shubho wrote:
Can you help me with how to add axis and scale in that graph?

    Looks like you've got it drawing stuff, so that's good, you're now used to how
    to draw stuff in FLTK.

    But adding tick marks and axes to your app the way it's written now will be very
    hard, because there's lots of magic numbers everywhere for scale and offset,
    and those magic numbers would have to be duplicated and finagled around to
    get the axes tick marks/labels to match up with your data.

    I'd suggest doing a second pass, designing your GRAPH class to be more
    generalized, so that any number of arrays of data can be passed in,
    allowing each data array to be assigned colors, shapes for data points,
    and have it automatically calculate the min/max of the data on entry
    so that these values can be drawn along the axes, no matter what the
    range of values is.   

    There's a few things you can do to your code to make it easier how to
    draw the axes and tick marks.

    First, start by naming all the visual elements in your graph, e.g.


    In general replace all the 'magic numbers' used throughout the code with
    the meaningful names you've chosen, and then use these names throughout
    your code, so the variables are consistent.

    And choose names for non-visual elements too.
    For instance an X and Y scale values would be useful, so you can easily change
    the drawing scale of the equation, and the tick marks adjust accordingly.

    The code that draws the equation has to use the same scale that draws the
    tick marks and axes, so use these values consistently. And drawing the graph
    needs to be within an area that allows for the tick marks and axes to be drawn
    around it. So you could call that region the 'margin', and the data's xywh are
    all drawn within that margin.

    Then break up the drawing tasks into separate methods within the class.
    e.g. draw_data() to draw the actual arrays of data in their chosen colors, and
    e.g. draw_axes() to draw the axes and tick marks in the chosen font/font size/colors.

    Basically design the widget in such a way that it operates how you'd want it to
    work for any kind of data you want to throw at it. Maybe not just sine waves,
    but even random data from the rand() function.

    Try to keep it generalized, and by doing that, it makes it easier to keep the
    tick marks in sync with the graph, and allows things to be changed easily
    (such as the scale, or colors, adding more data, etc)

    For instance:

            #define MY_RED      0xff0000
            #define MY_BLUE     0x0000ff
            #define SINE_SCALE  100
            #define COS_SCALE   100
            [..]

            GRAPH->add_data(sine_array,   MY_RED,  GRAPH_FILLED_CIRCLE, SINE_SCALE);
            GRAPH->add_data(cosine_array, MY_BLUE, GRAPH_FILLED_SQUARE, COS_SCALE);
   
    With that, each call to add_data() just appends another array to the class,
    and calculates the min + max range of the data which will help drawing the
    tick marks.

    And you'd probably want to separately control the overall scale and number
    of tick marks drawn along the X and Y axes separately. As you might want
    to scale the data down more so that it doesn't exactly draw to the edges
    of the graph, but leaves some extra white space.

    So in short, break the visual problem up into parts and name all the parts,
    and in the code, break up drawing the elements into parts, and name those
    methods accordingly.

    It's complex as a whole, but I think you'll find the large problem breaks up
    into simpler pieces that are each easy to program, and will fit together nicely
    when done, if you've designed well for it.

    Another thing is try to design the app to be a normal widget, so the app
    can just call the normal application loop, instead of having to use WAIT
    and emulating the timing loop for drawing yourself.

    If you want the data to draw up slowly, you can use an FLTK timer to
    step through drawing the data, so the widget redraws itself each tick
    of the timer, just drawing a little bit more from the array each time.

Daniel G.

unread,
Apr 8, 2021, 7:18:12 PM4/8/21
to fltk.general
Just FYI, there is also the MathGL project, which implements an FLTK based widget to plot mathematical functions.

http://mathgl.sourceforge.net/doc_en/Main.html

BR,
Giri

Daniel G.

unread,
Apr 8, 2021, 7:26:14 PM4/8/21
to fltk.general
MathGL is the only library I am aware of, which has advanced plotting features AND can be statically linked.

Here an example: https://www.youtube.com/watch?v=VgP-K-JWE7Q

Greg Ercolano

unread,
Apr 8, 2021, 9:11:56 PM4/8/21
to fltkg...@googlegroups.com

On 4/8/21 4:18 PM, 'Daniel G.' via fltk.general wrote:

Just FYI, there is also the MathGL project, which implements an FLTK based widget to plot mathematical functions.

http://mathgl.sourceforge.net/doc_en/Main.html


    Wow, that's pretty impressive.. lots of pics of various graph screenshots here:
    http://mathgl.sourceforge.net/doc_en/Pictures.html

    ..and in particular I suppose what the OP is looking for specifically:
    http://mathgl.sourceforge.net/doc_en/axis-sample.html#axis-sample

Daniel G.

unread,
Apr 9, 2021, 3:52:26 AM4/9/21
to fltk.general
Here an concrete example how the FLTK widget can be used as drawing backend:


(The examples on the MathGL homepage will only generate files containing the plot)

Rob McDonald

unread,
Jul 18, 2024, 6:29:49 PM7/18/24
to fltk.general
On Friday, March 19, 2021 at 12:17:29 AM UTC-7 geert karman wrote:
I started off (years ago) with the Cartesian library, but needed some of my own special stuff and found it hard to integrate it there (one of the new features is a possibility to zoom in). Inspired by It, I ended up rewriting my own from scratch. I happen to have taken it up again not long ago and am right in the middle of turning it into a library. Still work to do but it almost meets my own needs now. Screenshot attached. Anyone interested, drop me a note.

Geert,

Not sure how I missed this when it was fresh, but I would be interested in your take on a FLTK  plotting library.

Thanks for sharing,

Rob

 
Reply all
Reply to author
Forward
0 new messages