Two years ago, I've written a post on how to call
gnuplot from C++. It turns out the most viewed post of my posts. If you're missing it, click
here.
Now as I am developing
an UI for my program, I begin to use C# now. And here the old problem comes back again: how to call
gnuplot from C#.
Instead of using Foms of C#, I get used to using WPF. However, as we are talking about the C#, so it should work
in both structures.
Here we go -- How to call
gnuplot from C#.
I'll skip the basics of C# and assume that you all know how to start a project (here I use desktop WPF) or create a button click event.
1 At you design view, create a button click, all the coding we're going to do is just within this event. So it has the most flexibility for using elsewhere.
2 Preparation. Only two preparation we need:
a, add " using System
.IO;" and "using System
.Diagnostics" at the top of the file (as you can see in the previous picture). In WPF, these are not added by default. So don't forget to add them before you
procceed.
b.
download and copy the
gnuplot folder to the location where your setup would be. I recommend
download the "gp466-win32
.zip" and unzip
it then you get a folder named "
gnuplot". I put it under the debug folder as shown in this picture. You can put it
any where as you like, later in the code we have to specify the location of it.
3 set up a new process and specify the path of gnuplot, using StreamWriter to communicate with gnuplot. I will give three examples here to show the usage.
3.1 Simple case: function plot:
private void Button_Click(object sender, RoutedEventArgs e)
{
Process plotProcess = new Process();
plotProcess.StartInfo.FileName = @"D:\Project\VisualGnuplot\VisualGnuplot\bin\Debug\gnuplot\bin\gnuplot.exe";
plotProcess.StartInfo.UseShellExecute = false;
plotProcess.StartInfo.RedirectStandardInput = true;
plotProcess.Start();
StreamWriter sw = plotProcess.StandardInput;
String strInputText = "plot sin(x)\n";
sw.WriteLine(strInputText);
sw.Flush();
MessageBox.Show("Close the gnuplot Window? " );
sw.Close();
plotProcess.Close();
}
Then debug it.
if you click on the button, it should appear like this:
notice that if I added a MessageBox to keep the
gnuplot window. If you omit it, there will be only a flash and you can't see anything. Another thing is that here the output terminal for
gnuplot is the interactive mode, so it's very convenient for a single plot use. For example, in 3D plot you could change the view with
mouse.
3.2 normal case: plot external data file.
here suppose that we have a "3d.txt" file whose content is like (don't forget to include
# as comment and blank line for 3D plot in
gnuplot! I put this data file under the Debug folder as well, you can see this from previous screenshot):
# X Y Z
0 1 2
0 2 4
0 3 8
0 4 16
0 5 32
1 1 5
1 2 3
1 3 5
1 4 3
1 5 5
2 1 32
2 2 16
2 3 8
2 4 4
2 5 2
3 1 3
3 2 9
3 3 27
3 4 81
I
purposedly write only four elements in "3" while for "0" to "2" each of them has five
element to indicate that you don't have to have the same shape in 3D line plot.
what we need to do is modify the code sent to
gnuplot.
Simply as it is:
private void Button_Click(object sender, RoutedEventArgs e)
{
Process plotProcess = new Process();
plotProcess.StartInfo.FileName = @"D:\Project\VisualGnuplot\VisualGnuplot\bin\Debug\gnuplot\bin\gnuplot.exe";
plotProcess.StartInfo.UseShellExecute = false;
plotProcess.StartInfo.RedirectStandardInput = true;
plotProcess.Start();
StreamWriter sw = plotProcess.StandardInput;
//String strInputText = "plot sin(x)\n";
String strInputText = "splot \"3d.txt\" using 1:2:3 with lines\n";
sw.WriteLine(strInputText);
sw.Flush();
MessageBox.Show("Close the gnuplot Window? " );
sw.Close();
plotProcess.Close();
}
Now the result is:
I think now you
have get a sense on how to use it now. Like in the C++ case, we sent all the commands to the
gnuplot and let it work. But
pratically, we need lots of settings to plot a graph we want, such as colors, labels and legends. Most of the case, we'd like the ability to
derectly output the image itself. I think now you should know how to do it. So let's give a simple last example to show how to do it: plot an external data file and output the image.
3.3 plot an external data file and with external plot setting file
suppose we write another file "
sp.plt" like this:
set terminal pngset output "plot.png"
splot "3d.txt" using 1:2:3 with lines
and now we read in these commands with StreamReader (not StringReader as I was cheated by the auto correction!)
private void Button_Click(object sender, RoutedEventArgs e)
{
Process plotProcess = new Process();
plotProcess.StartInfo.FileName = @"D:\Project\VisualGnuplot\VisualGnuplot\bin\Debug\gnuplot\bin\gnuplot.exe";
plotProcess.StartInfo.UseShellExecute = false;
plotProcess.StartInfo.RedirectStandardInput = true;
plotProcess.Start();
StreamWriter sw = plotProcess.StandardInput;
//String strInputText = "plot sin(x)\n";
//String strInputText = "splot \"3d.txt\" using 1:2:3 with lines\n";
String strInputText;
StreamReader sr = new StreamReader("sp.plt");
strInputText = sr.ReadToEnd();
sr.Close();
sw.WriteLine(strInputText);
sw.Flush();
// MessageBox.Show("Close the gnuplot Window? " );
sw.Close();
plotProcess.Close();
}
note that because we output the image, so we don't need the
gnuplot window again. This will be
handful when we have lots of files to plot. And there should be a
png file generated now.
(
a window flashed and disappeared)
Summary:
Now we could use the
gnuplot from C# in a flexible way.
Further thing you might be interested is as
following: a.
on the designer view design the setting
pannel; b, write the setting parameters from the user and save it to a
plot setting file; c, plot the data (
ouput from code or external ones) to
image; d, display the image as you want
to the window.
PS. I'm quite busy with my work so I didn't check the comments very often. But you can still leave your comments there that might be helpful for other readers or I will reply to it when I see it.