Reputation: 2565
I would like to plot some data with gnuplot inside a MATLAB script, instead of using the custom MATLAB plotting environment.
Take the following example, here I generate some random data and store it in a text file:
% Generate data
x = 0:10;
y = randi(100,size(x));
% Store data in 'xy.txt'
fileID = fopen('xy.txt', 'w');
for i = 1:numel(x)
fprintf(fileID, '%f %f\n', x(i), y(i));
end
fclose(fileID);
Now I use MATLAB's system
to pipe commands to gnuplot:
% Call gnuplot to do the plotting tasks
system('gnuplot &plot ''xt.txt'' &exit &');
However, I am not constructing this last instruction correctly since it only opens the gnuplot console but doesn't execute the commands.
Additionally, instead of saving the data in a text file in an intermediate step, I would prefer doing this direct approach.
How should I construct my system
instruction properly?
NOTE: There is a similar question for Linux, I am running Windows.
Upvotes: 3
Views: 2320
Reputation: 2565
This answer is based on John_West answer, which was very helpful. I have translated his GNU Octave code into MATLAB syntax.
I found this page helpful to understand the differences between GNU Octave and MATLAB, in terms of code syntax. And this page helpful to understand the escape sequences on GNU Octave strings (which are in fact, the same as in C).
These are the conversions I made:
"
string delimiter with '
\"
escape sequence with "
\'
escape sequence with ''
Furthermore, I made the following transformations:
sprintf
wherever there is an escape sequence.strcat
removes trailing ASCII white-space characters. (You can read about this in the documentation and this answer).This approach works very well.
% checked to work under Matlab R2015a + gnuplot 5.0 patchlevel 1
x = 0:10;
y = randi(100,size(x));
str = 'gnuplot -p plot.gp';
fileID = fopen('xy.txt', 'w');
for i = 1:numel(x)
fprintf(fileID, '%f %f\n', x(i), y(i));
end
fclose(fileID);
f2 = fopen('plot.gp', 'w');
fprintf(f2, 'plot ''xy.txt'' using 1:2');
fclose(f2);
system(str)
This script will open a gnuplot window with the plot. MATLAB will not resume the execution of the script until you close the plot window. If you want a continuous flow of execution, you can automatically save the plot (for example as a .png, among other formats) with the command:
fprintf(f2,'set terminal png; set output "figure.png"; plot ''xy.txt'' using 1:2');
as John_West explains in his comment.
This approach is under exploration. No successful results have been achieved yet (at least John_West and I did not get any plot). I am including my MATLAB code as I transcribed it from John_West answer:
x = 0:10;
y = randi(100,size(x));
str = sprintf('gnuplot -p -e "plot ''-'' using 1:2');
for i = 1:numel(x)
str = strcat(str, sprintf('\n%f %f', x(i), y(i)));
end
str = strcat(str, sprintf('\ne"'), sprintf('\n'));
system(str)
This code does not terminate by itself, so you will need to manually resume the execution by entering the command e
in the MATLAB command line.
Upvotes: 1
Reputation: 2399
Print all commands to temporary file plot.gp
and pass it to gnuplot
.
You are running Windows, so change /usr/bin/gnuplot
to gnuplot
(may work) or your full location of gnuplot
executable (would work)
% checked to work under octave 3.6.4 + gnuplot 4.6
x = 0:10;
y = randi(100,size(x));
str="/usr/bin/gnuplot -p plot.gp"
fileID = fopen('xy.txt', 'w');
for i = 1:numel(x)
fprintf(fileID, '%f %f\n', x(i), y(i));
end
fclose(fileID);
f2=fopen('plot.gp', 'w');
fprintf(f2, "plot 'xy.txt' using 1:2");
fclose(f2);
system(str)
Using one long command
However, plot '-' ... makes gnuplot 4.6 (Linux) hang in any case with -p or --persist option. You can check it on your gnuplot version in Windows.
x = 0:10;
y = randi(100,size(x));
str="/usr/bin/gnuplot -p -e \"plot \'-\' using 1:2\n";
for i = 1:numel(x)
str=strcat(str,sprintf('%f %f\n',x(i),y(i)));
end
str=strcat(str,"e\"\n");
system(str)
Also, as @Daniel said, you have a limit on a string length, so it is definitely better to use temporary file then a long-long command.
Upvotes: 2