3

Creating a normiles stack diagram works perfectly fine, now I want to use a different color for the boxes fitting in a specific range.

For this, I adopted the following:

set palette maxcolors 2
set palette defined  ( 0 '#C0504D', 1 '#00B059')

plot dataFileCity using (rounded(stringcolumn(1) eq city  ? $2 : NaN)):
(100 / (bin_width * STATS_records)):($2 > 1300 ? 0 : 1) 
smooth frequency with boxes palette

If column 2 has a value highter than 1300 I would like to have a different color.

Which is based on: Normalized histograms in gnuplot with added function plot And Color bars in different colors for some specific values in Gnuplot

However, I am afriad that the smooth frequency makes the thing not work. How can I pass the value such that is creates the a different color?

Community
  • 1
  • 1
significant
  • 153
  • 7
  • You can't mix smoothing and variable colors. If you need to check if the final value is above 1300, then you can write the smoothed values to a temporary file with `set table` . If you need to check if a single value of all values contributing to the sum is above 1300 you must use an external tool. – Christoph Nov 21 '13 at 14:34
  • It concerns the x-axis, so for all contributions to all x-values below <1300 I want to have specific color, the same for >1300. Let me study `set table in the mean while – significant Nov 21 '13 at 14:40

2 Answers2

0

I know this is nearly 8 years old, but I had the same issue and based on Christoph's comment above I was able to figure out a way.

Below is the graph I wanted:

enter image description here

However selecting certain rows only by way of the ternary and NaN does not play nice with smooth freq, and my histogram was wrong (seemed bins were drawn over one another and frequencies weren't as high as they should've been).

This did not work:

plot \
    'filename' using ($1 >= 0 ? $1 : NaN) notitle smooth freq with boxes fillcolor rgb "green", \
    'filename' using ($1 <  0 ? $1 : NaN) notitle smooth freq with boxes fillcolor rgb "red"

In the manual for gnuplot 5.4.2, this section describes an experimental feature which, combined with set table, allowed me to achieve the above graph.

[EXPERIMENTAL] To select only a subset of the data points for tabulation you can provide an input filter condition (if ) at the end of the command. Note that the input filter may reference data columns that are not part of the output. This feature may change substantially before appearing in a released version of gnuplot.

plot <file> using 1:2:($4+$5) with table if (strcol(3) eq "Red")

-- p207 gnuplot v5.4.2 manual

So the approach is:

  • Use set table $my_data_block_green to set the next plot command to output to the $my_data_block_green data block. We'll create one data block for each colour and this is the first.
  • Use plot <file> with table if (<condition_for_green>) to write to the green data block only rows matching <condition_for_green>.
  • Use set table $my_data_block_red (as in point 1).
  • Use plot <file> with table if (<condition_for_red>) to write to the red data block only rows matching <condition_for_red>.
  • Cease writing plot commands to tables with unset table.
  • Plot as normal, referencing the data blocks instead of <file>.

Relevant code (not the full code for graph above):

set table $db1
plot <filename> using 7:(1) with table if ($7 >= 0)

set table $db2
plot <filename> using 7:(1) with table if ($7 < 0)

unset table

plot \
    '$db1' using $1:.. .. fillcolor rgb "green", \
    '$db2' using $1:.. .. fillcolor rgb "red"

Hope that saves someone a few mins.

TKF
  • 138
  • 1
  • 10
0

Adding to @TKF's answer... There is no need to split the smooth freq data into two tables. Instead, plot it into one table and set the color via lc rgb variable and by defining an appropriate function. The following example works for gnuplot>=5.2, with some modifications also with earlier versions.

Code:

### histogram with split colors
reset session

# create some random test data
set print $Data
    do for [i=1:2000] {
        print sprintf("%g",int(invnorm(rand(0))*100))
    }
set print

stats $Data u 1 nooutput
xmin = STATS_min
xmax = STATS_max
N = 20
myWidth = (xmax-xmin)/N
bin(col) = myWidth*floor(column(col)/myWidth)+myWidth/2.

set boxwidth myWidth
set key noautotitle
set style fill solid 0.3
set grid x,y

set table $Histo
    plot $Data u (bin(1)) smooth freq 
unset table

myColor(col) = column(col)<0 ? 0xff0000 : 0x00cc00

plot $Histo u 1:2:(myColor(1)) w boxes lc rgb var 
### end of code

Result:

enter image description here

theozh
  • 22,244
  • 5
  • 28
  • 72