使用 GNUPlot 从单个数据集中绘制多个图形
Multiple graphs from a single data set with GNUPlot
我正在尝试使用 gnuplot v5.4 从一个数据集中生成多个图表,尽管每个图表使用来自集合的 select 数据。
我为我正在开发的一个小程序生成统计信息,并将它们写入 CSV 文件:
(这种 CSV 格式正是我取得最大进展的格式 - 我愿意改变)
TotalPlayerCount,22
BluePlayerCount,10
RedPlayerCount,12
BluePlayerScoreTotal,50
RedPlayerScoreTotal,60
下面给了我下面的图表:
cat <<"EOF" | gnuplot -p
$db <<DB
TotalPlayerCount,22
BluePlayerCount,10
RedPlayerCount,12
BluePlayerScoreTotal,50
RedPlayerScoreTotal,60
DB
set terminal windows size 2000,1000 enhanced font 'Arial,8'
set datafile separator ','
set yrange [0:100]
set boxwidth 0.1 relative
set style fill solid 1.0
plot $db using 2:xticlabel(1) notitle with boxes linestyle 1
EOF
我的目标是:
我用这个实现了:
cat <<"EOF" | gnuplot -p
$db <<DB
TotalPlayerCount,22
BluePlayerCount,10
RedPlayerCount,12
BluePlayerScoreTotal,50
RedPlayerScoreTotal,60
DB
set terminal windows size 2000,1000 enhanced font 'Arial,8'
set datafile separator ','
set yrange [0:100]
set boxwidth 0.1 relative
set style fill solid 1.0
set multiplot layout 1,2
plot $db using 2:xticlabel(1) every ::1::2 notitle with boxes linestyle 1
plot $db using 2:xticlabel(1) every ::3::4 notitle with boxes linestyle 1
unset multiplot
EOF
是否有更好或更惯用的方法 select 从数据文件中绘制 'rows' 的内容?这些索引(在 every
子句中)工作正常,但看起来很脆弱。
我以前使用过这样的技巧,其中在 using
中返回未定义的三元将导致 gnuplot 忽略该行(例如,也许我可以根据字符串比较将它用于 select)但是那看起来也没有更优雅,我真的不喜欢它使 plot
命令变得多么复杂。
如果您能灵活处理输入数据,我会按以下方式组织:
我不会将所有内容都转储到一个文件中并再次将其分开,而是创建两个文件,例如'Counts.dat'
和 'Scores.dat'
.
在下面的(复制和粘贴)示例中,它包含在带有数据块 $Counts
和 $Scores
的代码中,但是,如果您的数据在文件中,只需跳过数据块和绘图命令将其分别更改为 'Counts.dat'
和 'Scores.dat'
。
您不一定需要数据中的总数,gnuplot 可以为您完成这项工作。
此外,在下面的示例中,我为框的颜色引入了第三列。检查以下示例作为进一步优化的起点。
代码:
### multiplot with boxes and total sum
reset session
$Counts <<EOD
Red 12 0xff0000
Green 5 0x00cc00
Blue 10 0x0000ff
Yellow 7 0xffff00
EOD
$Scores <<EOD
Red 60 0xff0000
Green 30 0x00cc00
Blue 50 0x0000ff
Yellow 80 0xffff00
EOD
set yrange[0:100]
set boxwidth 0.5 relative
set style fill solid 1.0
set key left noautotitle
set grid x,y
set multiplot layout 1,2
set title "Counts"
plot sum=0 $Counts u 0:(sum=sum+column(2),column(2)):3:xtic(1) w boxes lc rgb var, \
keyentry w p ps 0 ti sprintf("Total count: %d",sum)
set title "Scores"
plot $Scores u 0:2:3:xtic(1) w boxes lc rgb var
unset multiplot
### end of code
结果:
加法:(一个数据块或文件中的所有数据)
代码:
### multiplot with boxes and total sum in a single file
reset session
$AllInOne <<EOD
# counts
Red 12 0xff0000
Green 5 0x00cc00
Blue 10 0x0000ff
Yellow 7 0xffff00
# scores
Red 60 0xff0000
Green 30 0x00cc00
Blue 50 0x0000ff
Yellow 80 0xffff00
EOD
set yrange[0:100]
set boxwidth 0.5 relative
set style fill solid 1.0
set key left noautotitle
set grid x,y
set multiplot layout 1,2
set title "Counts"
plot sum=0 $AllInOne u 0:(sum=sum+column(2),column(2)):3:xtic(1) index 0 w boxes lc rgb var, \
keyentry w p ps 0 ti sprintf("Total count: %d",sum)
set title "Scores"
plot $AllInOne u 0:2:3:xtic(1) index 1 w boxes lc rgb var
unset multiplot
### end of code
为您提供更“可读”语法的一种可能性是使用 columnheaders
,为此您需要转置您的数据集。您不一定需要使用逗号;空格或制表符也可以解决问题:
$db <<DB
TotalPlayerCount BluePlayerCount RedPlayerCount BluePlayerScoreTotal RedPlayerScoreTotal
22 10 12 50 60
DB
设置布局:
set xrange [0:3]
set yrange [0:100]
set boxwidth 0.5
set style fill solid 1.0
现在您可以 select 您想要使用 column("string")
绘制的列,这将为您提供正确的 y 值。至于 x 值,我只是为第一个图取常数 1,为第二个图取 2。为了生成 xticlabels,必须重复字符串:
plot $db u (1):(column("BluePlayerCount")):xticlabels("BluePlayerCount") w boxes not, \
$db u (2):(column("RedPlayerCount")):xticlabels("RedPlayerCount") w boxes not
或者,您可以从 plot 命令中删除 xticlabels
部分,而是使用:set xtics ("BluePlayerCount" 1, "RedPlayerCount" 2)
您还可以进一步自动化绘图:
whattoplot_1 = "BluePlayerCount"
whattoplot_2 = "RedPlayerCount"
x_pos_1 = 1
x_pos_2 = 2
set xtics (whattoplot_1 x_pos_1, whattoplot_2 x_pos_2)
plot $db u (x_pos_1):(column(whattoplot_1)) w boxes not, \
$db u (x_pos_2):(column(whattoplot_2)) w boxes not
根据你最终想要达到的效果,你可以考虑使用数组并遍历元素:
array whattoplot[2] = ["BluePlayerCount", "RedPlayerCount"]
plot for [i=1:|whattoplot|] $db u (i):(column(whattoplot[i])) w boxes not
我希望这能给你一些灵感,让你继续前进!
我正在尝试使用 gnuplot v5.4 从一个数据集中生成多个图表,尽管每个图表使用来自集合的 select 数据。
我为我正在开发的一个小程序生成统计信息,并将它们写入 CSV 文件:
(这种 CSV 格式正是我取得最大进展的格式 - 我愿意改变)
TotalPlayerCount,22
BluePlayerCount,10
RedPlayerCount,12
BluePlayerScoreTotal,50
RedPlayerScoreTotal,60
下面给了我下面的图表:
cat <<"EOF" | gnuplot -p
$db <<DB
TotalPlayerCount,22
BluePlayerCount,10
RedPlayerCount,12
BluePlayerScoreTotal,50
RedPlayerScoreTotal,60
DB
set terminal windows size 2000,1000 enhanced font 'Arial,8'
set datafile separator ','
set yrange [0:100]
set boxwidth 0.1 relative
set style fill solid 1.0
plot $db using 2:xticlabel(1) notitle with boxes linestyle 1
EOF
我的目标是:
我用这个实现了:
cat <<"EOF" | gnuplot -p
$db <<DB
TotalPlayerCount,22
BluePlayerCount,10
RedPlayerCount,12
BluePlayerScoreTotal,50
RedPlayerScoreTotal,60
DB
set terminal windows size 2000,1000 enhanced font 'Arial,8'
set datafile separator ','
set yrange [0:100]
set boxwidth 0.1 relative
set style fill solid 1.0
set multiplot layout 1,2
plot $db using 2:xticlabel(1) every ::1::2 notitle with boxes linestyle 1
plot $db using 2:xticlabel(1) every ::3::4 notitle with boxes linestyle 1
unset multiplot
EOF
是否有更好或更惯用的方法 select 从数据文件中绘制 'rows' 的内容?这些索引(在 every
子句中)工作正常,但看起来很脆弱。
我以前使用过这样的技巧,其中在 using
中返回未定义的三元将导致 gnuplot 忽略该行(例如,也许我可以根据字符串比较将它用于 select)但是那看起来也没有更优雅,我真的不喜欢它使 plot
命令变得多么复杂。
如果您能灵活处理输入数据,我会按以下方式组织:
我不会将所有内容都转储到一个文件中并再次将其分开,而是创建两个文件,例如'Counts.dat'
和 'Scores.dat'
.
在下面的(复制和粘贴)示例中,它包含在带有数据块 $Counts
和 $Scores
的代码中,但是,如果您的数据在文件中,只需跳过数据块和绘图命令将其分别更改为 'Counts.dat'
和 'Scores.dat'
。
您不一定需要数据中的总数,gnuplot 可以为您完成这项工作。
此外,在下面的示例中,我为框的颜色引入了第三列。检查以下示例作为进一步优化的起点。
代码:
### multiplot with boxes and total sum
reset session
$Counts <<EOD
Red 12 0xff0000
Green 5 0x00cc00
Blue 10 0x0000ff
Yellow 7 0xffff00
EOD
$Scores <<EOD
Red 60 0xff0000
Green 30 0x00cc00
Blue 50 0x0000ff
Yellow 80 0xffff00
EOD
set yrange[0:100]
set boxwidth 0.5 relative
set style fill solid 1.0
set key left noautotitle
set grid x,y
set multiplot layout 1,2
set title "Counts"
plot sum=0 $Counts u 0:(sum=sum+column(2),column(2)):3:xtic(1) w boxes lc rgb var, \
keyentry w p ps 0 ti sprintf("Total count: %d",sum)
set title "Scores"
plot $Scores u 0:2:3:xtic(1) w boxes lc rgb var
unset multiplot
### end of code
结果:
加法:(一个数据块或文件中的所有数据)
代码:
### multiplot with boxes and total sum in a single file
reset session
$AllInOne <<EOD
# counts
Red 12 0xff0000
Green 5 0x00cc00
Blue 10 0x0000ff
Yellow 7 0xffff00
# scores
Red 60 0xff0000
Green 30 0x00cc00
Blue 50 0x0000ff
Yellow 80 0xffff00
EOD
set yrange[0:100]
set boxwidth 0.5 relative
set style fill solid 1.0
set key left noautotitle
set grid x,y
set multiplot layout 1,2
set title "Counts"
plot sum=0 $AllInOne u 0:(sum=sum+column(2),column(2)):3:xtic(1) index 0 w boxes lc rgb var, \
keyentry w p ps 0 ti sprintf("Total count: %d",sum)
set title "Scores"
plot $AllInOne u 0:2:3:xtic(1) index 1 w boxes lc rgb var
unset multiplot
### end of code
为您提供更“可读”语法的一种可能性是使用 columnheaders
,为此您需要转置您的数据集。您不一定需要使用逗号;空格或制表符也可以解决问题:
$db <<DB
TotalPlayerCount BluePlayerCount RedPlayerCount BluePlayerScoreTotal RedPlayerScoreTotal
22 10 12 50 60
DB
设置布局:
set xrange [0:3]
set yrange [0:100]
set boxwidth 0.5
set style fill solid 1.0
现在您可以 select 您想要使用 column("string")
绘制的列,这将为您提供正确的 y 值。至于 x 值,我只是为第一个图取常数 1,为第二个图取 2。为了生成 xticlabels,必须重复字符串:
plot $db u (1):(column("BluePlayerCount")):xticlabels("BluePlayerCount") w boxes not, \
$db u (2):(column("RedPlayerCount")):xticlabels("RedPlayerCount") w boxes not
或者,您可以从 plot 命令中删除 xticlabels
部分,而是使用:set xtics ("BluePlayerCount" 1, "RedPlayerCount" 2)
您还可以进一步自动化绘图:
whattoplot_1 = "BluePlayerCount"
whattoplot_2 = "RedPlayerCount"
x_pos_1 = 1
x_pos_2 = 2
set xtics (whattoplot_1 x_pos_1, whattoplot_2 x_pos_2)
plot $db u (x_pos_1):(column(whattoplot_1)) w boxes not, \
$db u (x_pos_2):(column(whattoplot_2)) w boxes not
根据你最终想要达到的效果,你可以考虑使用数组并遍历元素:
array whattoplot[2] = ["BluePlayerCount", "RedPlayerCount"]
plot for [i=1:|whattoplot|] $db u (i):(column(whattoplot[i])) w boxes not
我希望这能给你一些灵感,让你继续前进!