gnuplot smooth frequency with conditional formatting - plot

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?

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:
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.

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:

Related

Gnuplot does not plot (blank) a contour map

I am new to gnuplot and trying to plot a contour plot with xyz data which is in text file.
I have tried many different methods but it gives only blank plot.
DATA is in Google Drive : https://drive.google.com/open?id=1x-NAD9Vs8wyv9QbDgjcaT9SujHlHChAd
set contour base
set pm3d
unset surface
set view map
set xrange [1000:4000]
set yrange [0.2:0.395]
set zrange [0:40000]
splot "relax.txt" using 1:2:3
Followed error message:
Warning: Single isoline (scan) is not enough for a pm3d plot.
Hint: Missing blank lines in the data file? See 'help pm3d' and FAQ.
The problem is that gnuplot requires an empty line after each (matrix) row (e.g. when column 1 value changes).
So you can insert the empty lines yourself manually or with an external tool or let gnuplot do this. You plot your data into a dummy-table (a datablock) and then you print it to another datablock and insert an empty line when the value of column 1 changes. A bit cumbersome but it works. Requires gnuplot >=5.2.
Code:
### contour plot, addding empty lines to raw data
reset session
set contour base
set pm3d
set cntrparam level 10
unset surface
set view map
set size 0.9,0.9 # shrink the size a little otherwise colorbar numbers will be outside canvas
### insert empty lines everytime when column 1 changes its value
set table $Dummy # initialize a table (datablock) named $Dummy
plot "relax.txt" u 1:2:3 with table # plot datafile into a datablock $Dummy
unset table # close the table
set print $Data # set print output to datablock $Data
check="" # initialize your comparison variable to empty string
do for [i=1:|$Dummy|] { # loop the datablock $Dummy by lines
if (check ne word($Dummy[i],1)) { print "\n" } # comparison: if values are not equal insert a line
print $Dummy[i] # print current line to datablock $Data
check = word($Dummy[i],1) # assign latest value to variable "check"
}
set print # close the datablock $Data
splot $Data u 1:2:3 w l notitle
### end of code
Result:

Plot new series based on value within column

Lets assume we have a data like :
1383.77224864627 1910.27446956287 13
2022.08962783969 1870.75968662608 13
2244.59435149955 2334.43843428841 13
3223.73010669775 2409.90834407782 15
708.364446053354 3199.82702811616 15
1190.6942303025 2634.33363259192 15
1749.15599203783 2716.76870380272 19
2227.80906774024 3119.99529267007 19
Is it possible to plot series, based on values in the 3rd column ?
Desired result in this example would be to have 3 series with different colors on one plot.
I'm aware that I can create new series with :
plot 'datafile' using col1:col2, '' using col1:col3
or by using new line between series in datafile but thats not I would like to do.
Thanks !
Edit: I'm using gnuplot version 5.0
Building on my 2012 answer and my understanding of what you want, this should help:
set palette defined ( 13 "blue", 15 "red", 19 "green")
unset key
unset colorbox
plot [500:3500][1800:3500] "x" u 1:2:3 with points palette ps 3 pt 5
which yields
EDIT:
One could also define a continuous palette and let the actual colors be allocated depending upon their value within that scale. In practice:
set palette defined ( 0 "blue", 20 "green", 40 "red")
unset key
set colorbox # for demo purpose
plot [500:3500][1800:3500] "x" u 1:2:3 with points palette ps 3 pt 7
which brings
for the given data set. Colors will change when new series is added.
You would need to filter the datafile first and then plot individual parts separately:
#prepare the command responsible for filtering the data file of interest
#select all rows the value in the 3rd column of which is equal to val
filterData(fname, val)=sprintf("<gawk '$3==%d' %s", val, fname)
#show individual dependencies in one plot
plot for [sval in "13 15"] \
filterData('datafile.dat', int(sval)) w lp t sprintf('value %s', sval)
This would give you:

How to manipulate with the data in a cycle gnuplot 4.6

I would like to plot several lines in a gnuplot (version 4.6 or 5.0) using loop and during plotting manipulate with the data.
For simple plotting of the data (without manipulation) i use
plot for [i=2:100] 'data.dat' u 1:i with lines lt 1 lc rgb 'blue' notitle
and everything is fine: Normal result
but!
when i'm trying to manipulate with data in this code:
plot for [i=2:100] 'data.dat' u 1:(i-0.3) with lines lt 1 lc rgb 'blue'
the gnuplot resist to my manipulation and gives the strange result:
The strange result after the second code and assumptions to manipulate on the date. Also I've tried ($i-0.3) instead of (i-0.3) and also without brackets, all this doesn't work. Could anyone help?
Thanks in advance.
Use column(i) to access a column's value for calculation, if the column number is given by a variable i:
plot for [i=2:100] 'data.dat' u 1:(column(i)-0.3)

How to plot an histogram and a constant line from different files

I'm new to gnuplot and I have a problem:
I have 2 different text files, the first one (file1.txt) is something like this:
Switch,Port,BPS
S1,1,5464091.33
S1,3,5465677.33
S2,2,5463298.00
S2,3,5462729.67
S3,1,5461340.67
S3,3,5461772.33
and I plot "file1.txt" with an histogram:
plot avg_file using 3:xticlabels(stringcolumn(1)."-".stringcolumn(2)) title columnheader
this works fine.
Now I have file2.txt which contains a single value:
AVG_BPS
4844714.81
I would like to plot this value as a constant horizontal line over the previous graph (histogram).
This is my complete script:
# Terminal definition (PNG image)
set term png
# Settings
set datafile separator ","
set output 'myplot.png'
set style data histogram
set style histogram cluster gap 1
set style fill solid border -1
set boxwidth 1
# Graph and Axis titles
set title "BPS"
set xlabel "Switch-Port"
set ylabel "bits-per-second"
# Plot
plot "file1.txt" using 3:xticlabels(stringcolumn(1)."-".stringcolumn(2)) title columnheader
Here is myplot.png:
Thanks
probably the best is to do a stats:
stats 'file2.txt' u 1
hor_value=STATS_min
and then add to your plot:
plot "file1.txt" using 3:xticlabels(stringcolumn(1)."-".stringcolumn(2)) title columnheader, hor_value
or alternatively put a line on top (before the last plot):
set arrow nohead from graph 0, hor_value to graph 1, hor_value front

Plotting multiple plots on same page using gnuplot; trying to avoid text on the plot

I am trying to plot multiple plots on the same page of gnuplot postscript output. Although, I like the way the plots are looking, what can I do to avoid the text on the plots? (See the code below, and the plot too). If you cannnot see the text on the plot, it says: "'../binsam_Omidi.dat' using 5:($1==1?$6:1/0)"
reset
set term postscript eps color size 10,10
set output "../Results/phasespace_bins.ps"
set multiplot layout 4,5 # engage multiplot mode
set size square
set size ratio -1
plot '../binsam_Omidi.dat' using 5:($1==1?$6:1/0) w p ps 1 pt 7
set size 0.4,0.4 # set the size of the second plot in plot units
set origin 0.15,0.5 # set the origin for the second plot
plot '../binsam_Omidi.dat' using 5:($1==1?$6:1/0) w p ps 1 pt 7
unset multiplot
Thanks!
That is the legend (key) entry of the plot. You can specify your own title with the title option, like
plot x title 'my title'
If you don't specify your own title, the code of the plot command is used. This is what you see.
To have no key entry for a single plot use notitle or title ''. If you don't want to have any key at all use unset key.

Resources