跳转到内容

Unix 命令行中的即席数据分析/使用 gnuplot 进行快速绘图

来自 Wikibooks,开放书籍,为开放世界

示例 - 创建散点图

[编辑 | 编辑源代码]

早起的鸟儿有虫吃?让我们看看一个人上班时间和收入之间的关系。收入记录在第 297-303 列,上班时间记录在第 196-198 列,以十分钟为间隔编码。此管道提取、清理和格式化数据

$ cat pums_53.dat | grep "^P" | cut -c196-198,297-303 | grep -v "^000" | 
grep -v " $" | perl -pe 'substr($_,3,0)=" ";' > time_vs_income

grep 命令排除了任何字段为空的记录,perl 脚本在两列之间插入一个空格,以便 gnuplot 可以将列分开。在 gnuplot 中绘图很简单

$ gnuplot

        G N U P L O T
        Linux version 3.7 patchlevel 1
        last modified Fri Oct 22 18:00:00 BST 1999

Terminal type set to 'x11'
gnuplot> plot 'time_vs_income' with points

以及生成的绘图

请记住,x 轴上的 0 代表午夜,20 代表午夜后 200 分钟,即大约凌晨 3:20。传统的第一个和第二个班次开始时密度增加很明显。工作时间规律的人显然收入更高。计算每个时间段的平均收入会很有趣,但这会让命令行 perl 脚本变得非常复杂。以下是它所有恐怖的辉煌

$ cat pums_53.dat | grep "^P" | cut -c196-198,297-303 | grep -v "^000" | 
grep -v " $" | perl -ne '/(\d{3})(\d{7})/; $sum{$1}+=$2; $count{$1}++; END { foreach $k
(keys(%count)) {print $k," ",$sum{$k}/$count{$k},"\n"}}' | sort -n > time_vs_avgincome

如果您好奇,可以自己绘制结果。

示例 - 使用 gnuplot 创建条形图

[编辑 | 编辑源代码]

让我们看看华盛顿州历史上移民的比例。移民年份记录在第 78-81 列,0000 代表该人是土生土长的公民。我们可以对 cut、grep、sort 和 uniq 应用常用的技巧,但在文本输出中来回滚动时很难看到模式,如果我们可以看到一个图表会更好。

$ cat pums_53.dat | grep "^P" | cut -c78-81 | grep -v 0000 | sort | uniq -c | head -10
 2 1910
 7 1914
12 1919
 7 1920
 6 1921
 5 1922
 7 1923
 5 1924
 8 1925

Gnuplot 是一个非常好的绘图工具,但它希望类别标签放在前面,计数放在后面,因此我们需要编写一个 perl 脚本来反转 uniq 的输出并将结果粘贴到一个文件中。有关 perl 的 -a 和 -F 选项的详细信息,请参阅 perlrun(1)。

$ cat pums_53.dat | grep "^P" | cut -c78-81 | grep -v 0000 | sort | uniq -c |
perl -lape 'chomp $F[-1]; $_ = join " ", reverse @F' > year_of_immigration

现在我们可以使用 gnuplot 从文件内容中制作条形图。

gnuplot> plot 'year_of_immigration' with impulses

这是 gnuplot 生成的图形

在解释这个图表时要小心,只有还活着的人才能被计算,因此它自然会向上和向右移动(最近移民的人更有可能还活着)。也就是说,二战结束之后似乎移民人数有所增加,越南战争结束之后也出现了一个高峰。我仍然不明白 1980 年左右的峰值,请咨询你当地的历史学家。

[编辑 | 编辑源代码]

set term win; set grid;A1=-300;A2=250;n=360;z=2500;splot(x**2)/(A1**2) + (y**2)/(A2**2) - ((2*x*y)/(A1*A2))*cos(n-z) - (sin(n-z))**2

使用内联 perl 重写数据 · 附录

华夏公益教科书