Gnuplot:修正CSV生成的堆叠柱状图的X轴刻度与图例问题
Gnuplot堆叠柱状图问题修复
原始需求
要生成员工为X轴、累计工时为Y轴的堆叠柱状图,CSV数据如下:
id,title,alice,bob,charlie,diego foo,Foo Stuff,2,,3,1 bar,Bar Stuff,1,5,, baz,Baz Stuff,,1,8,5
原Gnuplot脚本:
set datafile separator ',' set style data histograms set style histogram columnstacked set style fill solid noborder set boxwidth 0.75 set xtics rotate by 90 right set grid ytics linestyle 0 set key outside set xlabel "Employee" set ylabel "Working hours" plot for [COL=3:*] 'example.csv' using COL title columnhead
问题1:X轴出现重复的diego标签
原因
原脚本按**列(员工)**循环绘图,Gnuplot默认会把每列对应的第一列数据(项目ID)当作x轴刻度,导致多组刻度叠加重复。
修复方法
手动指定X轴刻度为员工列表,同时用行号索引定位柱子位置:
- 用
set xtics直接定义员工名称和对应的位置(1到4,对应4个员工) - 绘图时使用
using 0:COL,0表示用行号作为x轴的位置索引,避免读取第一列作为标签
问题2:图例显示项目名称(第二列)
原因
原脚本把列标题(员工名)当作图例,而我们需要的是把每行的项目名称作为堆叠系列的图例。
修复方法
改为按**行(项目)**循环绘图,用每行的第二列(title)作为图例文本:
- 用
for [ROW=2:*]循环数据行(跳过第一行表头) - 用
columnhead(2)获取当前行的项目名称作为图例
修正后的完整脚本
set datafile separator ',' set style data histograms set style histogram columnstacked set style fill solid noborder set boxwidth 0.75 set xtics rotate by 90 right set grid ytics linestyle 0 # 手动设置X轴刻度:位置1-4对应四个员工 set xtics ("alice" 1, "bob" 2, "charlie" 3, "diego" 4) set key outside set xlabel "Employee" set ylabel "Working hours" # 按行循环(项目),每个项目对应一个堆叠系列,图例用第二列的项目名称 plot for [ROW=2:*] 'example.csv' every ::ROW::ROW using 0:3 title columnhead(2), \ for [ROW=2:*] '' every ::ROW::ROW using 0:4 title "", \ for [ROW=2:*] '' every ::ROW::ROW using 0:5 title "", \ for [ROW=2:*] '' every ::ROW::ROW using 0:6 title ""
脚本说明
every ::ROW::ROW表示只读取指定的行,确保每个项目系列对应正确的数据- 后续的
title ""是为了避免重复生成图例,只有第一个系列(alice列)会显示项目名称的图例
进阶优化版本(自动适配列数)
如果员工列数可能变化,可以用stats命令自动获取列数和表头,无需硬编码:
set datafile separator ',' # 先统计数据的列数和表头 stats 'example.csv' nooutput num_employees = STATS_columns - 2 # 减去前两列(id和title) # 提取员工名称列表(从第3列到最后一列) employee_names = '' do for [COL=3:STATS_columns] { employee_names = employee_names.' "'.wordhead(COL).'" '.COL-2.', ' } # 去掉最后一个逗号 employee_names = substr(employee_names, 1, strlen(employee_names)-2) set xtics (@employee_names) set style data histograms set style histogram columnstacked set style fill solid noborder set boxwidth 0.75 set xtics rotate by 90 right set grid ytics linestyle 0 set key outside set xlabel "Employee" set ylabel "Working hours" # 循环每个项目行,依次绘制每个员工列的数据 plot for [ROW=2:STATS_rows] 'example.csv' every ::ROW::ROW \ for [COL=3:STATS_columns] using 0:COL title (COL==3 ? columnhead(2) : "")
内容的提问来源于stack exchange,提问作者memowe
相关产品推荐
相关产品推荐

