matplotlib - 对特定类别栏进行分组并在 gnuplot 中提供 xtics 子类别
问题描述
我需要绘制三类数据:
- cat1(带有子类别 i1、i2、i3)
- cat2(带有子类别 p1、p2、p3)
- cat3(带有子类别 n1、n2、n3)
每个类别都应进行不同的分组和着色。在每个组中,我们需要将不同的模式分配给框和相应的子类别作为 xtic 标签,以便提供区分。
这是示例数据和代码。样本数据:sample.dat
cat1 i1 95.2162 0.817947 i2 96.2065 0.710029 i3 98.4846 0.58444
cat2 p1 96.899 0.502756 p2 97.9695 1.16202 p3 99.631 0.0911258
cat3 n1 99.4709 0.318714 n2 99.5897 0.234542 n3 99.9535 0.0507579
代码:
set terminal png
set output 'bar.png'
set style data histograms
set style fill solid 1 border lt -1
set boxwidth 0.9
set style histogram errorbars lw 3
plot 'sample.dat' using 3:4:xtic(2) title "cat1", \
'' using 6:7:xtic(5) title "cat2", \
'' using 9:10:xtic(8) title "cat3"
请找到图形输出。所需的输出是将条形分组为一种颜色,并且需要将特定的子类别作为 xtic 标签。但是这里的输出失败并在所有类别中显示 3 种颜色,并且每个组只有最后一个 xtic 出现。你能帮我理解我哪里出错了吗?
谢谢你。
解决方案
一种可能的解决方案是使用with boxes
绘图样式生成单独的组,然后叠加误差线。下面的脚本将 boxwidth 设置为 1,然后将各个组偏移固定数量(4 和 8)。由于每个组内只有 3 个框,这在组之间提供了足够的“间隙”(与每个框一样宽)。
$DATA <<EOD
cat1 i1 95.2162 0.817947 i2 96.2065 0.710029 i3 98.4846 0.58444
cat2 p1 96.899 0.502756 p2 97.9695 1.16202 p3 99.631 0.0911258
cat3 n1 99.4709 0.318714 n2 99.5897 0.234542 n3 99.9535 0.0507579
EOD
set terminal pngcairo enhanced rounded font ",16"
set output 'fig.png'
set style fill solid 1 border lt -1
set boxwidth 1.0
set linetype 42 lw 2 lc rgb 'black'
set yr [94:102]
set xtics out nomirror
plot \
$DATA using (0 + $0):3:xtic(2) w boxes lc rgb 'red' t 'cat1', \
$DATA using (0 + $0):3:4 w yerrorbars lt 42 t '', \
$DATA using (4 + $0):6:xtic(5) w boxes lc rgb 'green' t 'cat2', \
$DATA using (4 + $0):6:7 w yerrorbars lt 42 t '', \
$DATA using (8 + $0):9:xtic(8) w boxes lc rgb 'blue' t 'cat3', \
$DATA using (8 + $0):9:10 w yerrorbars lt 42 t ''
编辑:
从您的评论来看,我似乎误解了您的问题。为了对“每行”的框进行分组,您可以执行以下操作:
$DATA <<EOD
cat1 i1 95.2162 0.817947 i2 96.2065 0.710029 i3 98.4846 0.58444
cat2 p1 96.899 0.502756 p2 97.9695 1.16202 p3 99.631 0.0911258
cat3 n1 99.4709 0.318714 n2 99.5897 0.234542 n3 99.9535 0.0507579
EOD
set terminal pngcairo enhanced rounded font ",16"
set output 'fig.png'
set style fill solid 1 border lt -1
set boxwidth 1.0
set linetype 42 lw 2 lc rgb 'black'
set yr [94:102]
set xtics out nomirror
set lt 1 lc rgb 'red'
set lt 2 lc rgb 'blue'
set lt 3 lc rgb 'green'
plot \
$DATA using (4*$0):3:($0+1):xtic(2) w boxes lc variable t 'cat1', \
$DATA using (4*$0):3:4 w yerrorbars lt 42 t '', \
$DATA using (4*$0 + 1):6:($0+1):xtic(5) w boxes lc variable t '', \
$DATA using (4*$0 + 1):(1/0):($0+2) w boxes lc variable t 'cat2', \
$DATA using (4*$0 + 1):6:7 w yerrorbars lt 42 t '', \
$DATA using (4*$0 + 2):9:($0+1):xtic(8) w boxes lc variable t '', \
$DATA using (4*$0 + 1):(1/0):($0+3) w boxes lc variable t 'cat3', \
$DATA using (4*$0 + 2):9:10 w yerrorbars lt 42 t ''
这里的想法是,对应于第一批列的行的0, 4, 8
框放置在位置 ,对应于第二批的行的框放置在位置 ,1, 5, 9
最后是第三批2, 6, 10
。这有效地创建了分组i1,i2,i3
,p1,p2,p3
和n1,n2,n3
。该样式lc variable
确保每一行都有不同的颜色。但是,如果不进行任何调整,图例中的条形图都将具有相同的颜色(因为第一行始终对应于 group i1,i2,i3
)。为了解决这个问题,脚本使用:
$DATA using (4*$0 + 1):6:($0+1):xtic(5) w boxes lc variable t '', \
$DATA using (4*$0 + 1):(1/0):($0+2) w boxes lc variable t 'cat2'
在这里,第一个语句进行绘图,而第二个语句生成一个空图(由于未定义值1/0
),但使用偏移 1 的颜色索引,即,($0+2)
而不是($0+1)
。这实现了图例中的项目将获得正确的颜色(蓝色而不是红色)。
最后,该语句$DATA
表示一个数据块。旧版本的 Gnuplot(我猜是 5 之前的版本)不支持此功能,因此您可以替换$DATA
为包含包含数据的文件名称的变量。
编辑2:
更具体地说,例如表达式(4*$0 + 1):6:($0+1):xtic(5)
请求在 x 坐标处生成框,计算为行号的 4 倍(从 0 开始)加 1。框的高度取自第 6 列,颜色索引($0+1)
计算为 1加上行号,最后从第 5 列加载 xtic 标签。
推荐阅读
- php - 发布php后的jQuery ajax返回值
- javascript - 控制器中的 Ajax 在 php 中无法正常工作
- javascript - 防止 socket.io 向套接字发送垃圾邮件
- view - 显示当前日期的页面浏览量
- r - 以另一种货币进行网络抓取(多种选择)
- rtweet - 警告:/1.1/statuses/user_timeline.json - 未授权。使用 rtweet 检索 realDonaldTrump 推文时
- nlp - 我正在寻找错字/拼写错误的字符级别统计信息
- javascript - 更改 CSS 项的值
- r - 如何根据 R 中先前变量的条件创建新变量?
- android - 将 Paging 3 alpha 更新为稳定导致索引问题 Android