如何在MATLAB中将命令传送给gnuplot

3
我希望您能在MATLAB脚本中使用gnuplot绘制一些数据,而不是使用自定义的MATLAB绘图环境。
以下是一个示例,我在此生成一些随机数据并将其存储在文本文件中:
% 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);

现在,我使用MATLAB的 system 将命令传递到gnuplot:
% Call gnuplot to do the plotting tasks
system('gnuplot &plot ''xt.txt'' &exit &');

然而,我没有正确构建这个最后的指令,因为它只打开了gnuplot控制台,但没有执行命令。
此外,在中间步骤中,我不想将数据保存在文本文件中,而是更喜欢采用直接方法
我应该如何正确构建我的system指令?
注意:有一个类似的问题适用于Linux,但我正在运行Windows。

你试过这个吗?只要不处理大量数据,那个方法就没什么问题。你也可以使用为Java和Python实现的许多包装器API之一。两者都可以在MATLAB中使用。 - Daniel
我不知道如何从MATLAB中调用gnuplot,这是我发布问题的主要原因。我不知道什么是包装器API...我会去看看! - codeaviator
1
在Windows系统中,您使用system命令而不是unix。否则,操作方式相同。 - Daniel
谢谢你的建议,Daniel。为什么你认为这对于大量数据会有问题?那我应该生成一个数据文件吗? - codeaviator
1
仅仅存在一个限制(https://dev59.com/inA75IYBdhLWcg3wm6Uj) - Daniel
显示剩余2条评论
2个回答

2

使用临时脚本与gnuplot命令

将所有命令打印到临时文件plot.gp中,并将其传递给gnuplot

你正在运行Windows,所以将/usr/bin/gnuplot更改为gnuplot可能有效),或者将gnuplot可执行文件的完整位置(有效)。

% 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)

使用一条长命令

然而,在任何情况下,plot '-' ... 会导致gnuplot 4.6 (Linux)在-p或--persist选项下挂起。你可以在Windows中检查你的gnuplot版本。

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)

此外,正如@Daniel所说,您的字符串长度有限,因此最好使用临时文件而不是一个非常长的命令。

非常感谢John_West,我已经将你的两个脚本转换成MATLAB语法。使用“带有gnuplot命令的临时脚本”版本会生成图形,但是除非关闭图形窗口,否则脚本不会终止(MATLAB状态:繁忙...)。使用“一个长命令”的版本不会生成任何图形,也不会终止。如果合适的话,我会根据你的答复编辑我的帖子,展示我的进展。 - codeaviator
@Cebri “脚本没有终止”,我认为它不应该终止。如果你想立即终止它,从gnuplot命令(str)中删除-p选项。但我认为,图形将只是闪烁并消失。然后,如果你想要不连续处理,你就不应该使用屏幕(如wxt终端),而是将其写入png:添加到plot.gp命令:set terminal png;谢谢你测试“使用一个长命令” - 当使用-e时,似乎gnuplot无法正确处理plot '-' - John_West
打字错误,应该是“如果你想要持续处理”。 - John_West

1
这个答案基于John_West的回答,非常有帮助。我把他的GNU Octave代码翻译成了MATLAB语法。 我发现这个页面很有帮助,可以理解GNU Octave和MATLAB在代码语法方面的差异。这个页面对理解GNU Octave字符串中的转义序列(事实上与C中的相同)也很有帮助。 这是我所做的转换:
  • '代替"字符串定界符
  • "代替\\"转义序列
  • ''代替\'转义序列
此外,我还进行了以下变换:
  • 在所有存在转义序列的地方使用sprintf
  • 重新排列转义序列的使用,因为strcat会删除尾随的ASCII空格字符。(您可以在文档此答案中阅读有关此问题的更多信息)。

使用带有gnuplot命令的临时脚本

这种方法非常有效。

% 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)

这个脚本将打开一个带有绘图的gnuplot窗口。直到你关闭绘图窗口,MATLAB才会恢复脚本的执行。如果你想要连续执行,你可以使用命令自动保存绘图(例如保存为.png格式),如John_West在他的comment中所解释的那样。

使用一个长命令

这种方法正在探索中。目前还没有取得成功的结果(至少我和John_West没有得到任何绘图)。我将我的MATLAB代码包含在内,正如我从John_West的回答中记录的那样:
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)

这段代码本身不会自动终止,所以您需要在MATLAB命令行中输入e命令手动恢复执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接