gnuplot: Colour-coding specific / individual histogram bars - gnuplot

I am using feedgnuplot to create a barchart, in order to visually show how teams compare to each other (I'd use the term benchmarking, but that's not a suitable tag here).
What I would like to do is to colour one or more bars to indicate which team I'm working with.
Since pictures explain more, here is an example visually that I am attempting to reproduce:
Here we have several components: Firstly the horizontal line indicating the "group mean", and then four specific teams -- two of which are over-performing, and two of which are under.
Can you help with the red bars please?
Current attempt is produced with:
< ../gnuplot.csv /usr/bin/feedgnuplot --set 'style data histograms' --set 'style fill solid border lt -1' -xticlabels
The gnuplot command this generates is:
set grid
set boxwidth 1
histbin(x) = 1 * floor(0.5 + x/1)
set style data histograms
set style fill solid border lt -1
plot '-' using 3:xticlabels(2) notitle
2 "E" 8
3 "H" 7
4 "B" 6
5 "F" 5
6 "A" 4
7 "D" 3
8 "C" 2
e

From your example I don't see why you would need plotting style histogram. A simple bar chart with conditional color should be sufficient.
simply define a function based on your condition for bar coloring and use variable linecolor (check help lc variable).
if you want to plot the statistical mean value, use stats (check help stats).
the example below has just two columns column 1 text and column 2 numbers. Since you need an x-value for the bars, you take pseudocolumn 0, which is basically the row number with 0-based index (check help pseudocolumns).
Script:
### bar chart with conditional color
reset session
# create some random test data
set table $Data
set samples 26
y0 = 900
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
plot '+' u (alphabet[$0+1:$0+1]):(y0=y0-rand(0)*50) w table
unset table
myColor(col) = (_s=strcol(col), _s eq "C" || _s eq "J" || _s eq "T" || _s eq "X" ? \
0xff3333 : 0x3333ff)
set offset 1,1,0,0
set key noautotitle
set style fill solid 0.5
set yrange[0:1000]
stats $Data u 0:2 nooutput # get the mean value into variable STATS_mean_y
set label 1 at STATS_max_x, STATS_mean_y sprintf("mean=%.1f",STATS_mean_y) offset 0,0.7 right
plot $Data u 0:2:(myColor(1)):xtic(1) w boxes lc rgb var, \
STATS_mean_y w l lw 2 lc "web-green"
### end of script
Result:

Related

Gnuplot, change the color of data points and x-axis

I'm trying to get different points color and enter the points of second file on x-axis in the same graph.
I have two different files which contains : (y-axis:D,A,Q,F ; x-axis: 1-5 and 6-10)
1.file enter image description here
2. file enter image description here
Then I wrote this code to draw :
set style data labels
xcoord(N)= (N)
ycoord(N) = (column(0)+1)
symbol(N) = strcol(N) ne "/" ? strcol(N) : "/"
set xrange [0:10]
set yrange [0:5]
set ytics ("D" 1, "A" 2, "Q" 3, "F" 4)
plot for [N=0:6] 'doc.txt' using (xcoord(N)):(ycoord(N)):(symbol(N)):(symbol(N)) w labels tc lt 7 font "Helvetica,12" notitle, \
for [N=0:6] 'doc1.txt' using (xcoord(N)):(ycoord(N)):(symbol(N)):(symbol(N)) w labels tc lt 1 font "Helvetica,10" notitle
and currently the output looks like this:
graph of 1.file enter image description here graph of two data files enter image description here
As you can see, the all points are overlapping.
I want to use different colors for /, 5, g, 3 and o
and plot the points of second files in the x-axis 6-10.
How can I do that? Can someone help in correcting my commands.
Many thanks.
Not sure I understand the question fully, but to move the points from the second file over by six units on x you could modify the plot command to be:
plot for [N=0:6] 'doc.txt' using (xcoord(N)):(ycoord(N)):(symbol(N)):(symbol(N)) w labels tc lt 7 font "Helvetica,12" notitle, \
for [N=0:6] 'doc1.txt' using (6+xcoord(N)):(ycoord(N)):(symbol(N)):(symbol(N)) w labels tc lt 1 font "Helvetica,10" notitle
Can you clarify what color you want to use for the points? Your sample output does use a different color for the points in each file; is that not what you wanted?
Edit
I am making up a data format because you haven not shown any actual data, but perhaps the example below is enough to get you started.
$DATA << EOD
3 F / / 3 g 3
2 Q / / o / 5
1 A / o / / 5
0 D / / 5 / g
EOD
set xrange [0:7]
set yrange [-1:4]
set tics nomirror
set border 3
unset key
# These are the hexadecimal RGB representations of
# "red" "blue" "yellow" "green" "purple"
array colors = [0xFF0000, 0x0000FF, 0xFFFF00, 0x00FF00, 0xC080FF]
array symbol = ["/", "5", "g", "3", "o"]
color( sym ) = sum [i=1:5] (symbol[i] eq sym ? colors[i] : 0)
plot for [N=1:6] $DATA using (N) : (column(1)) : (strcol(N)) : (color(strcol(N))) \
with labels tc rgb variable font ":Bold"
Alternatively, you could do something with palette colors and numerical values rather than discrete RGB color names. That would be a different approach.
thank you very much for your answer. It's very very helpful.
[enter image description here][1]
[1]: https://i.stack.imgur.com/gLuoF.png
I can see now my graph, what I want to have.
Have a nice evening,! :)
Many thanks,
Chang.

gnuplot automatic stack bar graph

Here is my data set:
type size name
label_0 1 nameOfData_0
label_0 2 nameOfData_1
label_0 3 nameOfData_2
label_1 2 nameOfData_3
label_2 1 nameOfData_4
label_0 2 nameOfData_5
label_1 3 nameOfData_6
label_3 2 nameOfData_7
label_3 1 nameOfData_8
I would like the plot to looks like:
I would like each label to be a stack and each nameOfData_X to fit in the correct stack according to its size. If possible add also the legend for each element of the stack.
I know I could reformat the data to process it easily via gnuplot but I don't want to.
Any ideas on how I could display this graph via gnuplot?
Thanks for your help!
Maybe there is a way to achieve this with the gnuplot built-in stacked histogram style, check help histograms.
The following solution is not too obvious but seems to give the desired result and uses the plotting style with boxxyerror (check help boxxyerror).
you need a list of unique elements of column 1. Here it will be in the order of the first occurrences.
during plotting in loops you add your contributions depending on a "filter" function myAdd().
you change the color when the addition is zero (dy=0).
you add labels in a similar way with an offset
This code can probably be simplified but may act as a starting point.
Code:
### "manual" stacked histogram
reset session
$Data <<EOD
type size name
label_0 1 nameOfData_0
label_0 2 nameOfData_1
label_0 3 nameOfData_2
label_1 2 nameOfData_3
label_2 1 nameOfData_4
label_0 2 nameOfData_5
label_1 3 nameOfData_6
label_3 2 nameOfData_7
label_3 1 nameOfData_8
EOD
# get a unique list from datablock column 1
set table $Dummy
Headers = 1
addToList(list,col) = list.( strstrt(list,'"'.strcol(col).'"') > 0 ? '' : \
' "'.strcol(col).'"')
plot Uniques='' $Data u (Uniques=addToList(Uniques,1),'') skip Headers w table
unset table
N = words(Uniques)
Unique(i) = word(Uniques,i)
set xrange [1:N]
set xtics out noenhanced
set grid x,y
set offsets 0.5,0.5,0.5,0
unset key
set style fill transparent solid 0.7 border
myBoxWidth = 0.8
myAdd(colD,colF,i) = strcol(colF) eq Unique(i) ? column(colD) : 0
myLabel(col1,col2) = dy==0 ? '' : sprintf("%s\n%g",strcol(col1),column(col2))
plot for [i=1:N] y=y0=(c=1,0) $Data u (i):(dy=myAdd(2,1,i), y=y+dy,(y0+y)/2.): \
(myBoxWidth/2.):(y0=y,dy/2.):(dy==0?c:c=c+1) skip Headers w boxxy lc variable, \
for [i=1:N] y=y0=0 $Data u (i):(dy=myAdd(2,1,i), y=y+dy,(y0+y)/2.): \
(y0=y,myLabel(3,2)):xtic(Unique(i)) skip Headers w labels offset 0,0.5 noenhanced
### end of code
Result:

gnuplot histogram : negative values go down instead go up

I try to generate a histogram plot with gnuplot. I have positive and negative values. Positive values go to the top of the chart, but negative values go to the bottom of the chart..
I would like to change the base for go up and go down
from 0 to -100 for example.
Maybe, it's not the good type of graphic to do that ?
I have tried this :
gnuplot -e "set terminal png size 20000, 1500; set yrange [-100:*]; set title 'VU meter 0'; set style data histogram; set style histogram clustered gap 1; set style fill solid 1 noborder; plot 'testVUmeter0.tsv' using 2:xticlabels(1)" > out.png
Thanks
As far as I know the plotting styles histogram and with boxes always start at y=0.
Assuming I understood your question correctly, you want to shift this zero level e.g. to -100.
As long as you do not need an advanced histogram style but just simple boxes, one possible solution could be to use the plotting style with boxxyerror. Compared to #meuh's solution, here, gnuplot automatically takes care about the y-tics.
Code:
### shift zero for boxes
reset session
$Data <<EOD
A -20
B -140
C 100
D -340
E +250
F 0
EOD
myOffset = -100
myWidth = 0.8
set style fill solid 1.0
set arrow 1 from graph 0, first myOffset to graph 1, first myOffset nohead ls -1
set style textbox opaque
plot $Data u 0:2:($0-myWidth/2.):($0+myWidth/2.):(myOffset):2:xtic(1) w boxxyerror notitle, \
'' u 0:2:2 w labels boxed notitle
### end of code
Result:
You can calculate a new y value at each point, taking into account some wanted offset. For example, setting bot=-20 to give a bottom y value of -20 you can refer to ($2-bot) to convert, say, -5 to -5-(-20)=15` above 0.
set terminal png size 400,300
set output "out.png"
set style data histogram
set style histogram clustered gap 1
set style fill solid 1 noborder
bot=-20
set yrange [0:*]
set ytics ("-10" -10-bot, "0" 0-bot, "10" 10-bot, "20" 20-bot, "30" 30-bot)
plot "data" using (($2)-bot):xticlabels(1) notitle, \
"" using 0:($2+3-bot):(sprintf("%d",$2)) with labels notitle
with data of
1 33
2 44
3 22
4 -12
gives the plot:

How to plot a graph from multiple origins?

The image below is an example that I need to reproduce and I do not know where to start.
Could someone advise me? I have a certain familiarity with gnuplot. How do I create multiple origins?
Without knowing your data structure it is difficult to make any suitable suggestions.
Since there seems to be no interest of the OP for an answer anymore, I will make a suggestion for others.
And since no data is given, I will assume something.
The example data contains several profiles separated by two empty columns.
Here the y-values (z-values in OP's graph) are in column 1 (range 0 to 2), and the x-values (x-values in OP's graph) are in column 2 (range 0 to 1).
You have a conditional offset and scaling.
So, then simply implement this for your x,y data using the ternary operator, check help ternary.
draw the rectangle and overwrite the ytic labels 1 -->0 and 3 --> 2
the pseudocolumn -2, i.e. the zero-based data(sub)block number (check pseudocolumns), is assigned to x0 which is used as x-offset.
if x0<=0 scale your y-values by 1 otherwise 1.5, and offset your values by 1 or 0, respectively.
Script:
### conditional offsets and scaling
reset session
# create some test data
set samples 50
set table $Data
f(x,a) = a*(-(x-1)**2+1) + (rand(0)*0.2-0.1)*x*(x-2)
do for [i=-3:15] {
plot [0:2] '+' u 1:(f($1,(i+4)/20.)) w table
plot '+' u ("") every ::0::2 w table
}
unset table
set obj 1 rect from first -3, first 0 to first 0, first 1 fc "black" fs pattern 7
yScale(x) = x<=0 ? 1 : 1.5
yOffset(x) = x<=0 ? 1 : 0
set xrange[-3:16]
set xtic 5 out add ("" -2) # remove xtic at -2
set mxtics 5
set yrange[0:3]
set ytic 1 out add ("" 0, "0" 1, "" 2, "2" 3) # overwrite y-tics
set mytic 2
set key noautotitle
set grid x,mx ls 1 lc "black"
plot $Data u (x0=column(-2)-3, $2+x0):($1*yScale(x0)+yOffset(x0)):-2 w l lc var
### end of script
Result:

Custom legend (or text) gnuplot

I have a file with 3 columns, the first 2 are the position x y and the 3rd one I use it for define the color so I have something like this:
set palette model RGB defined ( 1 'black', 2 'blue', 3 'green', 4 'red')
unset colorbox
plot "file" u 2:1:3 w points pt 14 ps 2 palette, "file2" u 2:1:3 w points pt 14 ps 2 palette
Now the question: Is it possible to have a proper legend with this kind of point and COLOR?.
Since the points will have different colors (according to the pallete) I want to specify what means each color in the legend.
The only solution I was thinking was to write somewhere in the plot some text with the character of the point (in this case pt 14) and specify the color... but is not really a solution right?
So please help!
There is no option for this, you need to fiddle a bit. Here is YAGH (Yet another gnuplot hack) ;)
Assuming that your values are equidistantly spaced, you can use the '+' special filename with the labels plotting style.
To show only the custom key, consider the following example:
labels="first second third fourth"
set xrange[0:1] # must be set for '+'
set yrange[0:1]
set samples words(labels) # number of colors to use
key_x = 0.8 # x-value of the points, must be given in units of the x-axis
key_y = 0.8
key_dy = 0.05
set palette model RGB defined ( 1 'black', 2 'blue', 3 'green', 4 'red')
unset colorbox
plot '+' using (key_x):(key_y + $0*key_dy):(word(labels, int($0+1))):0 \
with labels left offset 1,-0.1 point pt 7 palette t ''
This gives (with 4.6.4):
As the set samples doesn't affect the data plots, you can integrate this directly in your plot command:
...
unset key
plot "file" u 2:1:3 w points pt 14 ps 2 palette, \
"file2" u 2:1:3 w points pt 14 ps 2 palette, \
'+' using (key_x):(key_y - $0*key_dy):(word(labels, int($0+1))):0 \
with labels left offset 1,-0.1 point pt 14 ps 2 palette
But you need to set a proper xrange, yrange and the values of key_x, key_y and key_dy.
This is not the most intuitive way, but it works :)
I have an alternative solution posted here:
Using Gnuplot to plot point colors conditionally
Essentially you plot once without a legend entry, then make dummy plots (with no data) for each point color/label.

Resources