GNUplot: how to plot rowstacked bar chart using color codes in data?

前端 未结 2 1768
梦毁少年i
梦毁少年i 2021-01-22 22:16

I have the following sample data:

col1 2 0 1 1
col2 1 1 0 0
col3 1 1 1 0
col4 1 1 2 1
col5 1 1 1 1
col6 2 0 1 1
col7 1 1 2 2
col8 1 1 2 1

colum

相关标签:
2条回答
  • 2021-01-22 23:00

    I would use the boxxyerrorbars plotting style. Despite the name, this is what you should use, when you want to plot "different" boxes.

    set key off
    unset border
    unset xtics
    unset ytics
    unset colorbox
    set style fill solid 1.0 border -1
    
    set palette model RGB defined ( 0 'orange', 1 'green', 2 'white')
    set cbrange [0:2]
    set style data boxxyerrorbars
    plot 'test.data' u 0:(0.5*$2):(0.5):(0.5*$2):4 lc palette,\
        '' u 0:($2 + 0.5*$3):(0.5):(0.5*$3):5 lc palette
    

    The boxxyerrorbars plotting style itself takes four columns, x, y, dx, and dy, and the lc palette uses the values in a fifth column to determine the color based on the current palette. To make the values in the palette absolute values I additionally set the cbrange to the same range which is covered by the palette.

    The expression using 0:(0.5*$2):(0.5):(0.5*$2):4 means:

    • Use the zeroth column (the row number) as x-value (box center)
    • the value in the second column multiplied by 0.5 as y-value (box center)
    • the number 0.5 as dx (half of the box width)
    • the value in the second column multiplied by 0.5 as dy-value (half of the box height)

    For the second plot part the y-value is the value in the second column plus half of the value in the third column.

    This solution can also easily be written to allow increasing the number of stacked boxes:

    set palette model RGB defined ( 0 'orange', 1 'green', 2 'white')
    set cbrange [0:2]
    set style data boxxyerrorbars
    
    last_column = 3
    plot for [i=2:last_column] 'test.data' \
        u 0:(0.5*column(i) + sum[c=2:(i-1)] column(c)):(0.5):(0.5*column(i)):(column(last_column + i - 1)) lc palette
    
    0 讨论(0)
  • 2021-01-22 23:04

    The colors are used to identify the corresponding parts in different stacks. Therefore they must follow the same order in all stacks which belong to the same histogram.

    But Gnuplot has a newhistogram command after which the colors can be "reset". And there is the multiplot command which can be used to add new histograms in a loop.

    Here is the part of the script which replaces the original plot command:

    set style line 1 lt 1 lc rgb "white"
    set style line 2 lt 1 lc rgb "green"
    set style line 3 lt 1 lc rgb "orange"
    
    stats 'test.data' u 2
    n = STATS_records
    
    set multiplot
    
    do for [i=0:n-1] {
       plot "test.data" u (0) ,\
            newhistogram "" at i, "" every ::i::i u (style = $5 + 1, 0), \
                                  "" every ::i::i u 2 ls style,          \
                                  "" every ::i::i u (style = $4 + 1, 0), \
                                  "" every ::i::i u 3 ls style
    }
    
    unset multiplot
    

    And this is how it works:

    • set style ...: Define the styles (colors) which will be used.
    • stats ...: Find the number of rows. We are going to plot an independent histogram for each row.
    • set multiplot: We will plot again and again on the same area.
    • "test.data" u (0): Plot nothing, but reserve space for all histograms.
    • new histogram "" at i: Initialize a new histogram without a name with offset i on the x axis. We are going to plot a single stack at this offset.
    • "" every ::i::i: Plot row i.
    • u (style = $5 + 1, 0): Plot nothing, but read the color of the current row from file.
    • u 2 ls style: Plot column 2 of the current row with the previously read style.

    I'm not sure whether this version is shorter than yours :)

    0 讨论(0)
提交回复
热议问题