LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 01-25-2012, 09:46 AM   #1
jtso8
Member
 
Registered: Apr 2011
Posts: 36

Rep: Reputation: 0
How to create a scatter plot in C++


I have created a program in C++ and would like to add a scatter plot of the data that the program creates but, I have had no luck in creating a scatter plot. What would be a good library to use and could you help me to configure the library onto my system? I have tried a few libraries but, have been unable to get any of them to work. My program's GUI is being created using the qt library.

Thanks,
 
Old 01-25-2012, 12:12 PM   #2
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,551
Blog Entries: 3

Rep: Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815
A scatter plot is very simple to generate without any library. If you want to draw an identity line, you can compute it pretty easily using a Linear least squares fit (of a line or expected curve) to your data.

I'm not up to date on Qt/C++, but if you want, I could whip up an example C99 program to show how to calculate and draw a scatter plot, as an image. Based on it, you should be able to create a scatter plot (into a QPixmap, displayable in a QLabel in your GUI). If you've written your own GUI code instead of using a GUI generator, adapting it should be no problem for you.

If you want more complex abilities, I believe gnuplot-cpp or gnuplot-iostream libraries might be worth a look -- but really, you could just use the gnuplot application itself directly from your own program. Using the application is not the most efficient way, but it is very easy to do (since gnuplot is available on all Linux distributions).

If you want to show the plot on demand in a separate window, interactively (zoomin in, for example), just execute gnuplot (using popen() for example) with the data in a temporary file as text, and writing the plotting commands (also as text) into the pipe (standard input for gnuplot). If you use a configuration file to contain the "template" for each plot (replacing placeholders like ${datafile} with variables like the path to the temporary data file), you can easily customize the plots without having to recompile your programs. Users might like that sort of a feature.

If you want to show the plot as part of your GUI, you can use the gnuplot application for that too. Instead of using the wxt or x11 terminal mode in gnuplot, you plot to a image, a temporary file. Otherwise this is exactly the same situation as above. In your GUI, you create a QPixmap object for each plot, use the .load() method to load the temporary image file generated by the gnuplot application, and display the plot as a QLabel in your GUI, using its .setPixmap() method to set the label to display the image of the plot. However, this plot will not be interactive, unlike the plot when using gnuplot to show it in a separate window.
 
Old 01-26-2012, 10:29 AM   #3
jtso8
Member
 
Registered: Apr 2011
Posts: 36

Original Poster
Rep: Reputation: 0
I want to program to be able to take predicted data, user data, and the combination of the two and graph them. I don't need to zoom or anything like that but, having the graphs in a separate window would be nice. Could you show me how to install/use gnuplot because I have install it from the Ubuntu software center but, the center says that the program is command line driven and I am not that familiar with the command line. Could you help me set gnuplot on my computer and make a simple graph that I could edit and base my many graph off of.

Thank for your help
 
Old 01-26-2012, 06:55 PM   #4
theNbomr
Senior Member
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 4,506

Rep: Reputation: 602Reputation: 602Reputation: 602Reputation: 602Reputation: 602Reputation: 602
Gnuplot comes with a pretty extensive set of documentation and examples. It would be wasteful to repeat all of that here. Go to the gnuplot homepage for links to lots of good information.

I have used gnuplot to plot data in real-time by piping commands and data to it from a Perl script. The update rates were very impressive. The same techniques can be applied with C.

Scatter plots aren't too difficult to create with the GD graphics library, if you just want static images. The difficult part in creating flexible graphing applications is calculating appropriate scales for the axes. If your application has data that always falls within a fixed range, then I think that method is potentially simpler for you.

--- rod.

Last edited by theNbomr; 01-26-2012 at 06:59 PM.
 
Old 01-27-2012, 09:57 PM   #5
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,551
Blog Entries: 3

Rep: Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815Reputation: 815
Here is a trivial example which should get you going:
Code:
gnuplot -p -e 'plot "-" u 1:2 notitle w points, (3*x*x-2*x*x*x) notitle w lines' <<ENDOFPOINTS
0.000000 -0.026221
0.050000 -0.013643
0.100000 0.062581
0.150000 0.025971
0.200000 0.112554
0.250000 0.125598
0.300000 0.247062
0.350000 0.249103
0.400000 0.350498
0.450000 0.390436
0.500000 0.486696
0.550000 0.573924
0.600000 0.689009
0.650000 0.694776
0.700000 0.823319
0.750000 0.815785
0.800000 0.909180
0.850000 0.946358
0.900000 0.955216
0.950000 0.953195
1.000000 1.000293
ENDOFPOINTS
Simply put, you execute gnuplot with -p parameter (so that it'll keep the window persistent), and one or more -e plotting-command , and feed the data to it via standard input.

From a C++ program, you can feed the data as native floats or doubles. Just use "-" binary format="%float%float" or "-" binary format="%double%double" to specify the binary format in the plotting command. You are not limited to 2D points, you can use as many columns as you like; gnuplot can even draw error bars and suchlike.

You can obviously use any file you like, as - is just a special one which means standard input (when naming data files).

Getting gnuplot to fit the data to some analytical function is just as easy, except that you need to use two pipes: one to send the data, and the other to read the fitted parameters. (Or, again, you could use files instead just as well.) Fortunately, gnuplot will always read all data first, and only output the fitted afterwards afterwards, so you don't need to use nonblocking pipes or reads/writes. There is no risk of deadlock.

The basic plotting command sequence I use for fitting e.g. a cubic function to data is this:
Code:
set print "/dev/null" ;
set fit logfile "/dev/null" errorvariables ;
fit (C0+x*C1+x*x*C2+x*x*x*C3) "-" u 1:2 via C0,C1,C2,C3 ;
set print "-" ;
print C0_err, C1_err, C2_err, C3_err
print C0, C1, C2, C3
For the above data, it will output
Code:
0.0205712962722043 0.182606980227572 0.430512738744765 0.282680275112865
-0.0116818581783575 -0.0153765054167047 3.1346215868934 -2.12470703988004
to standard output. The errors are on the first line, the actual fitted values on the second line. It is useful to redirect standard error to /dev/null, so you don't need to read the verbose fitting stuff.

Assume you do the fit first, and retrieve the fit parameters. (You could do it all at once, if you use temporary files, or more pipes, but let's keep this simple, eh? I prefer pipes, mostly because I like the inherent data security compared to files, but it should not be an issue here.)

See the persistent window you get if you supply the same data to
Code:
gnuplot -p -e '
   set title "Title of this plot" ;
   set xlabel "Horizontal axis" ;
   set ylabel "Vertical axis" ;
   set xrange [0:1] ; set yrange [-0.1:1.1] ;
   set key on inside center right ;
   plot 0 notitle w dots lt -1, 1 notitle w dots lt -1, "-" u 1:2 t "Data points" w points lt -1, (3*x*x-2*x*x*x) t "Original" w lines lt 2, -0.0116818581783575+x*(-0.0153765054167047+x*(3.1346215868934+x*(-2.12470703988004))) t "Fit" w lines lt 1'
Pretty nice, I'd say. You can tune the plot to your heart's content, just head out to the documentation for details. (The HTML one is for 4.2, see here for the other manual formats and versions.)

Gnuplot has a pretty friendly command language; I recommend you play with it. You can run it without any parameters, and give it the above commands interactively. Instead of "-", use "datafilename" to point it to the data to plot or fit.

If you want to save the plot as an SVG file for example, add
Code:
set terminal svg size 1280,720 dynamic enhanced
set output "output.svg"
at the start of the plotting commands. (If you want to put some example images onto a web page, SVG will give you the best quality. You can add a fallback image for Infernet Exploder 8 and prior versions.)

If you want the ability to close the window at will from your C++ program, I recommend you feed the plotting commands to it via standard input, and not in command-line parameters. That way the gnuplot window will close when you close the standard input, and you can update the plot whenever new data comes available, just by sending the plotting commands again (gnuplot will also re-read the data files, it won't cache them). If you do both fitting and plotting, it is usually better to use temporary files so that you only need to save the data once. I recommend using the binary format if you have very large datasets; printing and reading floating-point values from text is surprisingly slow compared to binary data.

If you are comfortable with simple shell scripts, I recommend you prototype the stuff with shell scripts first, considering all the different approaches (wrt. pipes or temporary files, persistent or input-controlled gnuplot window, and so on). It should be fun. Only start coding when you know the results will satisfy your needs.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
plot the xgraph adel.elkabbany Linux - Newbie 13 05-04-2011 11:52 AM
ETH offloading : scatter gather rotemaviv Linux - Networking 2 09-11-2008 07:05 AM
Converting a Histogram data into Scatter Plot data kushalkoolwal Linux - Software 2 09-08-2008 01:19 PM
3d and contour plot abhattacharya Linux - Software 3 01-26-2008 05:59 AM
compiling kernel for larger scatter gather list? niverson Linux - Software 0 09-20-2004 10:02 PM


All times are GMT -5. The time now is 03:23 PM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration