I'm attempting to graph some data with the GNUPlot library in C++.
I'm using Visual Studio 2022 with C++ 14. I also installed the boost libraries and am using the gnuplot-iostream.h file from dsthalke's GitHib repository.
As far as I understand, GNUPlot is different than MatPlotLib in the sense that it is a lower-level method of plotting data. As far as I understand, it consists of sending a series of commands via the << operator to a variable of type of Gnuplot.
I've been attempting to plot a few basic examples, from the GNUPlot documentation website and other examples.
Attempting to run Example 1 and 2 from the documentation website results in nothing happening, and the message pclose return error: No error.
Attempting to run any of the examples from this website also results in the same output.
That is, the following example code from the above website:
#include "gnuplot-iostream.h"
int main()
{
Gnuplot plot;
plot << "set dgrid3d 200,200,1";
plot << "set pm3d";
plot << "set palette";
plot << "set palette color";
plot << "set pm3d map";
plot << "splot \"sin_cos_data\"";
return 0;
}
Also results in nothing.
How does one graph data with GNUPlot in C++?
Is there a different set of examples that I have not yet come accross, that would be better for explaining how to do it?
Thanks for reading my post, any guidance is appreciated.
Well that's embarrassing...
Turns out I didn't actually install the GNUPlot library separately.
Talk about rushing...
Related
I'm attempting to save a GNUPlot plot as a PNG file. I'm using C++ 14 and Visual Studio 2022.
I have the following minimal example code:
#include <iostream>
#include <string>
#include <vector>
#include "gnuplot-iostream.h"
using namespace std;
int main()
{
vector<vector<float>> data = {};
data.push_back(vector<float>{0, 0, 0});
data.push_back(vector<float>{1, 1, 1});
data.push_back(vector<float>{2, 2, 2});
Gnuplot gp;
gp << "set terminal png\n";
gp << "set title 'test'\n";
gp << "set dgrid3d 100,100\n";
gp << "splot" << gp.file1d(data) << "with pm3d title 'test'" << endl;
gp << "set output 'test.png'\n";
gp << "replot\n";
return 0;
}
I noticed a really peculiar issue whenever I try to run the example code above;
Any command that is sent immediately after the set terminal png appears to get the first few of its characters removed/corrupted... In the example above, the command set title 'test' is the command sent immediately after, and this is a warning that's presented by the program console whenever I run the code above:
gnuplot> t title 'test'
^
line 0: invalid command
And my plot gets generated without the title test.
I can confirm that the set terminal png is the command that causes the issue, as if I add an additional set title 'test' command, the extra command gets read properly, and my plots gets generated with the test title.
I'm aware that the GNUPlot C++ implementation is known for not being too friendly with Windows OS (which is what I'm building this on), and I was just wondering whether this was an issue encountered by someone else, or whether this is one of those Windows artifacts.
Thanks for reading my post, any suggestions are appreciated.
This question already has answers here:
C++ Update console output
(4 answers)
Closed 5 years ago.
I'm developing some application in which I want to manipulate some data comming from the embedded system. So, what do I want to do is that I want to display the values which are comming on the same position where they were before, leaving the static text on the same place and not using new line. Being more specific, I want to output my data in form of a table, and in this table on the same positions I want to update that data. There is some analogy in Linux, when in the terminal there is some update of the value(let's say some progress) while the static text remains and only the value is changing.
So, the output should look like this:
Some_data: 0xFFFF
Some_data2: 0xA1B3
Some_data3: 0x1201
So in this case, "Some_data" remains unchanged on the same place, and only the data itself is updated.
Are there maybe some libraries for doing that? What about Windows Console Functions? Also, it would be very nice if it could be made in such a way, in which the console would not flick, like when you clear the console and print something back. Any hints or suggestions? Thanks very much in advance guys!
P.S. There is no need to write the code, I just need some hints or suggestions, with very short examples if possible(but not required).
On a *nix system you have two options.
1) If you want to manipulate the entire console in table form like you ask, then ncurses is the best option. The complete reference can be found here.
As you can see, that package is quite heavyweight and can often be overkill for simple projects, so I often use . ..
2) If you can contain your changing information on a single line, use the backspace escape char \b and then rewrite the information repeatedly to that line
For example, try this . . .
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
void writeStuff(int d)
{
cout << string(100,'\b') << flush;
cout << "Thing = " << d;
}
int main()
{
cout << "AMAZING GIZMO" << "\n============" << endl;
while(1) {
writeStuff(rand());
this_thread::sleep_for(chrono::milliseconds(250));
}
}
For a real world example, the sox audio console playback command uses this technique to good effect by displaying a bar chart made of console characters to represent the audio playback level in real time.
Of course, you can get more creative with the method shown above if your console supports ANSI escape sequences.
I have a QT C++ application that runs the Octave program using QProcess. I am able to communicate with it by reading the standard output/error and writing to it's standard input using write method (for example: octave->write("5 + 5\n");).
As I told you I get response from octave (from the above example I get "ans = 10").
However, when the command I write to Octave standard input has a "plot" (for example, a simple plot([1 2 3 4 5]);), the actual graphic is never shown. I know Octave runs gnuplot, I have it installed, and gnuplot_x11 too. I even change the gnuplot binary path in my Octave process by executing gnuplot_binary("/usr/bin/gnuplot"); from MY APPLICATION. I know it runs good because if I retrieve the new value I get it right. But I don't know why Octave doesn't show the graphic.
Here I start octave:
QStringList arguments;
arguments << "--persist";
octave->setProcessChannelMode(QProcess::MergedChannels);
octave->start("/usr/bin/octave", arguments);
Here I write commands to octave process:
if (octave->state() == QProcess::Running) {
QString command = widget.txtInput->toPlainText();
if (command.isEmpty()) {
return;
}
command += "\n";
octave->write(command.toAscii());
}
With this I print the octave response to a text edit:
widget.txtOutput->append(octave->readAll() + "\n");
And finally, I use this when the octave process starts:
QString gnuplot_path(tr("\"/usr/bin/gnuplot\""));
QString gnuplot_cmd(tr("gnuplot_binary(%1)\n").arg(gnuplot_path));
octave->write(gnuplot_cmd.toAscii());
I will appreciate any help you could give me.
Thanks in advance.
Octave, like Matlab, can be run in batch mode to perform computations without graphical UI. I assume that Octave detects that it is not run from an interactive session, and therefore automatically goes into batch mode. You would expect Octave to suppress graphical output (e.g. gnuplot output) when being in batch mode.
Try to force Octave into interactive mode by using the --interactive command line option:
http://www.gnu.org/software/octave/doc/interpreter/Command-Line-Options.html
I know you probably already solved your problem but this might be helpful for other...
You can try to add a command to save your plot in a temporary folder in your octave request.
Then display the graph in your ap
I am trying to call the gnuplot from c++. I am using wgnuplot for Windows and VS2005 c++.
The following statement works because it opens the gnuplot terminal
FILE *p = _popen("wgnuplot -persist","w");
But I cannot write anything there. My terminal is still blank even after running the following code.
fprintf(p, "set terminal x11 enhanced\n"); //set appropriate output terminal for the plot
fprintf(p, "set xlabel 'N'\n");//set xlabel
fprintf(p, "set ylabel 'error'\n");//set ylabel
Could you please tell me what might be the problem, i.e. why the terminal is blank and fprintf() doesn't seem to work?
Thanks,
Boris
Check that FILE pointer is not NULL:
if(!p)
// _popen() has failed...
I do not know if that helps you, but this is my approach of executing gnuplot from my C programs:
I create a template file (usually I do not delete it, so that it is easier to troubleshoot), where all the gnuplot commands are are scripted in.
I run gnuplot with
system("gnuplot <TemplateFile>")
If you are only interested in creating a plot, that his would do the job. If you are explicitly interested in the approach you described above then just disregard this posting ;)
Cherio Woltan
This is my first post and I'm quite a novice on C++ and compiling in general.
I'm compiling a program which requires some graphs to be drawn. The program create a .dat file and then i should open gnuplot and write plot '.dat'. That's fine.
Is there a way to make gnuplot automatically open and show me the plot I need? I should use some system() function in the code to call gnuplot but how can I make him plot what I need?
Sorry for my non-perfect English :s
Thanks for the attention anyway!
Depending on your OS, you might be able to use popen(). This would let you spawn a gnuplot process and just just write to it like any other FILE*.
If you have datapoints to plot, you can pass them inline with the plot "-" ... option. Similarly, you may want to explore set data style points/lines/linespoints/etc options.
Without pause or persist, gnuplot will terminate upon end-of-input-stream. In your example case, that would be when the end of the file is reached.
To produce (write) an output file (graph), use:
set terminal png small
set output "filename.png"
There's lots of options to set terminal. Png is usually there. If not, perhaps gif, tiff, or jpeg?
Watch out for overwriting the file!
You may want to use set size 2,2 to make a larger graph. Some set terminal variants also allow you to specify the size.
I'm learning this today too. Here is a small example I cooked up.
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char **argv) {
ofstream file("data.dat");
file << "#x y" << endl;
for(int i=0; i<10; i++){
file << i << ' ' << i*i << endl;
}
file.close();
return 0;
}
Save that as plot.cpp and compile that with g++:
g++ plot.cpp -o plot
Run the program to create the .dat file:
./plot
Save the following gnuplot script as plot.plt:
set terminal svg enhanced size 1000 1000 fname "Times" fsize 36
set output "plot.svg"
set title "A simple plot of x^2 vs. x"
set xlabel "x"
set ylabel "y"
plot "./data.dat" using 1:2 title ""
Run the script with gnuplot to generate your .svg file:
gnuplot plot.plt
The resulting plot will be in plot.svg. If you leave out the first couple lines that specify the output, it will render in a window. Have fun!
Sometimes it is as easy as one may think
gnuplot file
where file is neither your data nor your result file, but a file with the command you would type in the commandline. Just enter there your commands you need (either constant file you have or generate it).
After executing all commands in that file gnuplot exits.
Yes you can. You can make a file that has the commands you would otherwise type in to set up the plot and open gnuplot running from that file. This link has an article that explains how to do it. You can also output to an EPS or other graphical output formats and display the plot using another widget that reads in the file.
You may need to use the '-persist' flag to the command. I know that on *nix systems, this flag is required if you want the plot window to remain after the gnuplot process has completed and exited.
gnuplot -persist commands.gp
Also, you can put as many gnuplot commands as you like in the file. The file acts sort of like a batch script in this regard.
You might need to add a line
pause -1
This will show the plot until return has been pressed.
What you are probably seeing is that gnuplot runs and exits before the plot has time to be displayed.
You might need to set a terminal type. Read the gnuplot documentation about that.