我有一个.txt文件contatning点如下所示:
##x1 y1 x2 y2 123 567 798 900 788 900 87 89 ....
我想绘制使用gnuplot在.txt文件的行中链接每一对的二维图。
EDIT1:
我发现这个绘图点和线gnuplot ,但我不知道如何使用gnuplot在我的情况。
EDIT2:
图types没有限制。 正如我在这里看到的,我可以使用以下设置terminal到PNG:
set terminal png
对于线型,我在这里find这个例子:
set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 ps 1.5
而且不需要标记轴。
更新
根据您对行数和最大x,y维度的回答,我在这个答案底部的基于ImageMagick的原始方法显然不适合您的具体问题。 不过,我会把它留给其他人看,因为对于几十行来说,这样做是完全正确的。 我现在提供一个更合适的gnuplot
版本。
Gnuplot版本
如果你想用gnuplot
来做,它会看起来像这样:
set terminal png size 1000,1000 set output 'result.png' unset xtics unset ytics unset border plot 'lines.txt' using 1:2:($3-$1):($4-$2) with vectors nohead notitle
如果将其保存在文件calle plot.cmd
,则可以使用它运行
gnuplot < plot.cmd
如果你想要箭头,使用这样的变种:
set terminal png size 1000,1000 set output 'result.png' set style arrow 1 heads filled size screen 0.03,15,45 ls 1 unset xtics unset ytics unset border plot 'lines.txt' using 1:2:($3-$1):($4-$2) with vectors arrowstyle 1 notitle
Magick ++和C ++的答案
我决定制定一个Magick ++和C ++的答案,只是为了好玩。 代码如下所示 – 编译命令显示在顶部的注释中。
//////////////////////////////////////////////////////////////////////////////// // sample.cpp // Mark Setchell // // ImageMagick Magick++ sample code // // Compile with: // g++ sample.cpp -o sample $(Magick++-config --cppflags --cxxflags --ldflags --libs) //////////////////////////////////////////////////////////////////////////////// #include <Magick++.h> #include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> using namespace std; using namespace Magick; int main(int argc,char **argv) { InitializeMagick(*argv); // Create an image object, scaled by a factor of 100 to speed it up ! float scale=100.0; Image image("650x650","white"); // Construct drawing list std::list<Magick::Drawable> drawList; // Initial settings, blue lines 1 pixel thick drawList.push_back(DrawableStrokeColor("blue")); drawList.push_back(DrawableStrokeWidth(1)); // Read in lines from file, expected format "x1 y1 x2 y2" int lineno=0; std::ifstream infile("lines.txt"); std::string line; while (std::getline(infile, line)) { std::istringstream iss(line); int x1,y1,x2,y2; iss >> x1; iss >> y1; iss >> x2; iss >> y2; x1 = int(x1/scale); y1 = int(x2/scale); x2 = int(y1/scale); y2 = int(y2/scale); cout << "Line: " << ++lineno << " " << x1 << "," << y1 << " " << x2 << "," << y2 << endl; // Add this point to the list of lines to draw drawList.push_back(DrawableLine(x1,y1,x2,y2)); } // Draw everything using completed drawing list image.draw(drawList); // Write the image to a file image.write( "result.png" ); return 0; }
我用Perl生成了1000行随机测试数据,如下所示:
perl -E 'for($i=0;$i<1000;$i++){printf("%d %d %d %d\n",int rand 65000,int rand 65000, int rand 65000, int rand 65000);}' > lines.txt
结果如下所示:
原始答复
ImageMagick也可以很容易地完成,而ImageMagick已经安装在大多数Linux发行版上。 实际上在下面只有4行代码 – 其余全部是注释:
#!/bin/bash # Create the output image, 1000x1000 pixels say convert -size 1000x1000 xc:pink result.png # Suppressing lines that have a hash (#) at the start, read in the file "lines.txt" grep -v "^#" lines.txt | while read x1 y1 x2 y2; do echo Read line $x1,$y1 $x2,$y2 # Tell ImageMagick to draw the line on the image convert result.png -stroke blue -strokewidth 5 -draw "line $x1,$y1 $x2,$y2" result.png done
产量
Read line 123,567 798,900 Read line 788,900 87,89
你也可以使用rsvg-convert
(来自librsvg)或svg2png
。 这两个程序都希望SVG格式的inout文件将其呈现为PNG文件。 所以你需要转换你的
123 567 798 900 788 900 87 89
进入这种类型的东西
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <line x1="123" y1="567" x2="798" y2="900" stroke="blue" stroke-width="1"/> <line x1="788" y1="900" x2="87" y2="89" stroke="blue" stroke-width="1"/> </svg>
这可以用一个像这样的awk
脚本轻松完成:
awk ' BEGIN{ printf("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n") } { x1=$1; y1=$2; x2=$3; y2=$4; printf("<line x1=\"" x1 "\" y1=\"" y1 "\" x2=\"" x2 "\" y2=\"" y2 "\" stroke=\"blue\" stroke-width=\"1\"/>\n") } END{ printf("</svg>\n") }' points.txt
然后,您可以将其输出泵入上面提到的两个程序之一:
awk ... | rsvg-convert -b \#ffff00 > result.png