How can I put names on the chart with gnuplot? - linux

I have a txt file with names and quantities, for example:
1 70 cats
2 64 dogs
3 54 birds
4 30 turtles
how can I, only with gnuplot, generate a chart in which the names below and their respective quantities appear on the right ?

If the graph you want to create is just a point chart, you can do it by combining the with points and with labels plots. Here is a sample code.
$TestData <<EOD
1 70 cats
2 64 dogs
3 54 birds
4 30 turtles
5 25 "other animals"
EOD
set xrange [0:6]
set yrange [0:100]
set key noautotitle
plot $TestData using 1:2 with points ps 2 pt 7, \
"" using 1:2:(strcol(3)) with labels offset 0,-1 center, \
"" using 1:2:(strcol(2)) with labels offset 2,0 left

Related

Redrawing Excel figures on gnuplot

I was working on excel and drew two histograms shown below, I have been told to redraw them using gnuplot on windows which is very new to me.
The original graph that I want to redraw is this.
Area 1 Area 2
Case 1 Case 2 Case 1 Case 2
Parameter 1 36 66 31 72
Parameter 2 57 91 44 85
Parameter 3 62 90 50 85
My file is a text file and I wrote the above table as follows as I am not sure how to group the different columns together.
Area Area1 Area1 Area2 Area2
Case Case1 Case2 Case1 Case2
Parameter_1 36 66 31 72
Parameter_2 57 91 44 85
Parameter_3 62 90 50 85
I used the following commands and got a histogram that is grouped in the wrong way.
clear
reset
unset key
set style data histogram
set style fill solid border
set style histogram clustered
plot for [COL=2:5] 'date_mins.tsv' using COL:xticlabels(1) title columnheader
Kindly guide me on how to group columns together and also how to add the numbers on top of the bars. {The graph should be same as the one excel generated one.}
To be honest I'm regularly puzzled with histograms in gnuplot, apparently I'm not the only one. In gnuplot console, check help histograms.
Although, there are a few histogram examples on the gnuplot homepage, but of course not all possible variations can be covered.
Apparently, this plotting style is a bit confusing to understand.
This would maybe explain that there are more than 800 questions on SO on histograms with gnuplot.
I'm not sure if or how you can get your desired histogram efficiently, maybe there is an easy way.
I would do it "manually" with the plotting style with boxes.
Check the example below as a starting point. There are a few strange workarounds included, e.g. getting the titles into an array in an earlier plot for later use.
Code:
### special histogram
reset session
$Data <<EOD
Area Area1 Area1 Area2 Area2
Case Case1 Case2 Case1 Case2
"Parameter 1" 36 66 31 72
"Parameter 2" 57 91 44 85
"Parameter 3" 62 90 50 85
EOD
set style fill solid noborder
set boxwidth 0.8
set key noautotitle out center bottom horizontal reverse Left samplen 1 width 2
A=2 # Areas
C=2 # Cases
P=3 # Parameters
g=1 # gap
PosX(a,c,p) = ((a-1)*C*(P+g)) + (c-1)*(P+g) + p
PosY(a,c) = column((a-1)*C+c+1)
PosXArea(a) = (PosX(a,C,P)+PosX(a-1,C,P))*0.5
PosXCase(a,c) = (PosX(a,c,P)+PosX(a,c-1,P))*0.5
myColor(p) = int(word("0x5b9bd5 0xed7d31 0xa5a5a5",int(p)))
myValue(a,c) = strcol((a-1)*C+c+1)
set grid y
set xlabel "\n\n\n" # get empty space below the plot
set format x "" # no xtic labels
set yrange[0:]
array Titles[P] # array for titles
plot for [a=1:A] for [c=1:C] $Data u (PosX(a,c,$0)):(PosY(a,c)):(myColor($0+1)) skip 2 w boxes lc rgb var , \
for [a=1:A] for [c=1:C] '' u (PosX(a,c,$0)):(PosY(a,c)):(Titles[int($0+1)]=strcol(1), myValue(a,c)) skip 2 w labels offset 0,0.7, \
for [a=1:A] for [c=1:C] '' u (PosXCase(a,c)):(0):(myValue(a,c)) every ::1::1 w labels offset 0,-1, \
for [a=1:A] '' u (PosXArea(a)):(0):('\n\n'.myValue(a,1)) every ::0::0 w labels offset 0,-1, \
for [p=1:P] keyentry w boxes lc rgb myColor(p) ti Titles[p]
### end of code
Result:

gnuplot - how to plot invisible points so that the plot is only used to mark x-axis

I have the following data in data file test1.txt:
A 36 1
A 35 1
B 48 2
B 37 2
B 15 2
C 36 3
C 25 3
and test2.txt
A 16 1
A 25 1
B 38 2
B 45 2
C 36 3
the plotting is done as:
dat1="test1.txt"
dat2="test2.txt"
plot dat1 u ($3-0.2):2 w p t 'title 1', \
dat2 u ($3+0.2):2 w p t 'title 2', \
dat1 using 3:(0):xticlabels(1):x2ticlabels(1) notitle, \
dat2 using 3:(0):xticlabels(1):x2ticlabels(1) notitle
The whole point is to have the labels from the first column on the x axis. The issue is that the last two parts of plot
dat1 using 3:(0):xticlabels(1):x2ticlabels(1) notitle, \
dat2 using 3:(0):xticlabels(1):x2ticlabels(1) notitle
produce points at y=0. And because I cannot (or I do not know how to) use
plot dat1 u ($3-0.2):2:xticlabels(1) w p t 'title 1'
(since it plots the label at x coordinate $3-0.2 and not at $3, which i require), I am forced to do two more dummy plots, but they produce points and I do not know how to effectively avoid this other than shifting the outside of the range of the plot by e.g. dat1 using 3:(0):xticlabels(-1):x2ticlabels(-1) in the case of plotting only positive values. Is there any good way of solving this?
I don't really understand what you are trying to do with your data, however if you want to make the points over the x axis invisible you can set the line color to full transparency for the last two plots:
dat1 using 3:(0):xticlabels(1):x2ticlabels(1) linecolor "#FFFF0000" notitle, \
dat2 using 3:(0):xticlabels(1):x2ticlabels(1) linecolor "#FFFF0000" notitle
In recent versions of Gnuplot (link) it is possible to add transparency, in this particular case you want to set full transparency to the line color so that the points are invisible. The color format and transparency can be set using the hexadecimal notation #AARRGGBB where AA (alpha) controls how transparent the color is, for full transparency you want FF which is equivalent to 255, notice how my line color is RED but because is completely transparent we don't see it.
Plot with Full Transparency
My understanding of your question is the following: You have some data which you want to shift in x by +/-0.2 but the corresponding tic shouldn't be shifted.
You've been almost there. Of course, there are points at y=0 because you tell gnuplot to do so.
What you mean with "invisible" could of course be also achieved by fully transparent points, but the easier way is probably to "plot" the points at NaN, i.e. nowhere.
Code:
### plotting data with offset and tic without offset
reset session
set colorsequence classic
$Data1 <<EOD
A 36 1
A 35 1
B 48 2
B 37 2
B 15 2
C 36 3
C 25 3
EOD
$Data2 <<EOD
A 16 1
A 25 1
B 38 2
B 45 2
C 36 3
EOD
set offsets 0.5,0.5,0.5,0.5
set link x2
set x2tics
plot $Data1 u ($3-0.2):2 w p pt 7 t 'title 1', \
$Data2 u ($3+0.2):2 w p pt 7 t 'title 2', \
$Data1 using 3:(NaN):xtic(1):x2tic(1) notitle, \
$Data2 using 3:(NaN):xtic(1):x2tic(1) notitle
### end of code
Result:

How can I make a graphic with grouped values, stacked and labeled individually and in groups?

I would like to make a graphic like this, but I can not find similar information.
I have searched for examples on the internet, but the most I find are stacked graphs
!https://www.intechopen.com/media/chapter/54498/media/F1.png
The first thing is that you have the data in some useful format.
Since it will be probably an extra effort for gnuplot to group the values into your material categories (but can also be done), it is easier if you give numbers to each of your material categories. Then just plot points and labels. Do not hesitate to post the data and show your code how far you actually got.
Code:
### plot with labels
reset session
$Data <<EOD
Pt Metal 1 1750
Graphite Metal 1 3600
B_4C Carbide 2 2450
HfC Carbide 2 3800
Si_3N_4 Nitride 3 1900
HfN Nitride 3 3300
W_2B_5 Boride 4 2250
HfB_2 Boride 4 3400
Y_3Al_5O_{12} Oxide 5 1950
ThO_2 Oxide 5 3050
TiSi_2 Intermet. 6 1550
Zr_5Si_3 Intermet. 6 2250
Ti_3SiC_2 "Ternary\nComp." 7 1400
(Hf,Ta)C "Ternary\nComp." 7 3600
EOD
set bmargin 3
set xrange[0.5:8]
set ylabel "Melting temperatures (°C)
set yrange[1000:4500]
set grid xtics, ytics
plot $Data u 3:4:xtic(2) w p pt 7 notitle,\
'' u 3:4:1 w labels left offset 1,0 notitle
### end of code
Result:

Gnuplot filledcurves flip axes

There is a style to fill the space between two functions of x.
Examples of such plots can be found e.g. at http://gnuplot.sourceforge.net/demo/fillbetween.html
Is there any way to make similar plot, but with flipped x and y axes?
Here is the desired shape of a curve (without rotated/mirrored labels, titles and legends, of course)...
It could be done with closed contour (like last example here http://www.gnuplot.info/demo_svg_cvs/fillcrvs.html), but this would require reshuffling the data file. Any other options?
Thank you!
You can't do this directly. From help filledcurves:
The third variant fills the area between two curves sampled at the same set of
x coordinates. It requires three columns of input data (x, y1, y2).
I don't think you can specify (y, x1, x2) directly. As a workaround you can the area between the y axis and the larger function in some color, and then fill the area between the y axis and the smaller function in white:
x1(y) = cos(y)+1
x2(y) = cos(y)+2
xmax(y) = (x1(y) > x2(y) ? x1(y) : x2(y))
xmin(y) = (x1(y) < x2(y) ? x1(y) : x2(y))
plot '+' using (xmax($1)):1 with filledcurve y1, \
'+' using (xmin($1)):1 with filledcurve y1 fillcolor rgb "white"
This probably has to be tweaked a little if one or both of the two functions can be negative.
With gnuplot >=5.2 it could be tweaked even further because it allows arrays.
The following code shows a workaround how filled curves between vertically oriented curves can be realized. You can even use transparency. If you download the attached PNG you will notice that it actually has a transparent background. The basic idea behind this workaround is to make closed areas and fill them. For this, you need to reverse one border, concatenate the borders and plot them filled. Unfortunately, gnuplot has no function to reverse datapoints in a column, so you have to do it in a special procedure yourself.
The code:
### "Vertical" filledcurves
reset session
# create some dummy data
N = 50
set samples N
set xrange [-5:5]
set table $Data
plot '+' u (sin($1)):1:(rand(0)*0.3+1) with table
unset table
# put Borders into arrays
stats $Data nooutput
RowCount = STATS_records
array BorderX1[RowCount]
array BorderX2[RowCount]
array BorderY[RowCount]
set table $Dummy
plot $Data u (BorderX1[$0+1]=$1-$3):(BorderX2[$0+1]=$1+$3):(BorderY[$0+1]=$2) with table
unset table
# reverse BorderX2 and merge borders
set samples RowCount
set table $Border
plot '+' u (BorderX1[$0+1]):(BorderY[$0+1]) with table
plot '+' u (BorderX2[RowCount-$0]):(BorderY[RowCount-$0]) with table
unset table
# make the plot
set object 1 rect at 0,-3 size 10,0.5 fs solid 1.0 fc rgb "black" back
set yrange[-5:5]
plot \
$Border u 1:2 w filledcurves fc rgb "#AA00FF00" not,\
$Border u ($1*1.5):2 w filledcurves fc rgb "#AAFFFF00" not,\
$Data u ($1+2.5):2 w filledcurves y2 fc rgb "brown" not,\
$Data u 1:2 w l lw 8 lc rgb "blue" not,\
'+' u 1:(cos($1)-0.5):(cos($1)+0.5) w filledcurves lc rgb "grey" not,\
'+' u 1:(cos($1)):(1) w l lw 3 dt 2 lc rgb "white" not
### end of code
The result:
Update: These are two alternative and simpler approaches compared to my first answer. One of them works even with gnuplot 5.0.
The plotting style filledcurves (so far) can only fill between two y-curves with identical x-values. However, gnuplot can fill closed curves. So, make the curve closed. Like in my first answer, you can do this if you reverse one curve and add it to the other one.
The assumption for both scripts is that the data has a common y-column, i.e. is organized in 3 columns, e.g. here: y x1 x2
Data: SO50676753.dat (same as OP's data, from silver.dat in the gnuplot demo directory)
# y x1 x2
10 280 16.7332
20 191 13.8203
30 152 12.3288
40 150 12.2474
50 104 10.1980
60 77 8.7750
70 69 8.3066
80 60 7.7460
90 60 7.7460
100 51 7.1414
110 41 6.4031
120 34 5.8310
130 35 5.9161
140 34 5.8310
150 24 4.8990
160 24 4.8990
170 19 4.3589
180 21 4.5826
190 20 4.4721
200 18 4.2426
210 21 4.5826
220 15 3.8730
230 19 4.3589
240 12 3.4641
250 20 4.4721
260 20 4.4721
270 18 4.2426
280 18 4.2426
290 20 4.4721
300 12 3.4641
310 26 5.0990
320 17 4.1231
330 8 2.8284
340 6 2.4495
350 8 2.8284
360 10 3.1623
370 20 4.4721
380 14 3.7417
390 8 2.8284
400 10 3.1623
410 9 3.0000
420 8 2.8284
430 10 3.1623
440 13 3.6056
450 9 3.0000
460 5 2.2361
470 7 2.6458
480 11 3.3166
500 7 2.6458
510 9 3.0000
520 12 3.4641
530 4 2.0000
540 7 2.6458
550 10 3.1623
560 9 3.0000
580 8 2.8284
590 9 3.0000
600 5 2.2361
Script 1: (works with gnuplot>=5.0.0)
Here you assume that you have monotonic and unique y-values. With this you can use the option smooth unique (available at least in gnuplot 4.x versions) to reverse one curve. However, since this solution here uses datablocks and plotting style with table it requires at least gnuplot 5.0.0. Maybe with some workarounds and temporary files you can also get it to work with some 4.6 versions.
### fill between vertical curves
reset session
FILE = "SO50676753.dat"
set table $Temp
plot FILE u 1:2
plot FILE u (-$1):3 smooth unique
set table $Data
plot $Temp u 2:1 index 0 w table, \
'' u 2:(-$1) index 1 w table
unset table
set style fill solid 0.3
set grid x,y
plot $Data u 1:2 w filledcurves
### end of script
Script 2: (works with gnuplot>=5.2.0)
With this solution there are no special assumptions about the data, but since it uses indexing of datablocks it requires gnuplot>=5.2.0.
### fill between vertical curves
reset session
FILE = "SO50676753.dat"
set table $Temp1
plot FILE u 2:1 w table
set table $Temp2
plot FILE u 3:1 w table
unset table
set print $Data
do for [i=1:|$Temp1|] { print $Temp1[i] }
do for [i=|$Temp2|:1:-1] { print $Temp2[i] } # reverse data
set print
set style fill solid 0.3
set grid x,y
plot $Data u 1:2 w filledcurves
### end of script
Result: (same for both scripts):

How to remove palette colors heatmap

Is possible if heatmap palette(small rectangle on the right) to be removed?
this is my data
a b c
1 181 80 121 10 34 20
2 18 20 17 20 13 20
3 12 20 5 30 20 20
this is my gnuplot script
set term pos eps font 20
unset key
set nocbtics
set palette rgbformulae -7, 2, -7
set title "Faults"
set size 1, 0.5
set output 'heatmap2.eps'
YTICS="`awk 'BEGIN{getline}{printf "%s ",$1}' 'data2.dat'`"
XTICS="`head -1 'data2.dat'`"
set for [i=1:words(XTICS)] xtics ( word(XTICS,i) i-1 )
set for [i=1:words(YTICS)] ytics ( word(YTICS,i) i-1 )
set for [i=1:words(XTICS)] xtics ( word(XTICS,i) 2*i-1 )
plot "<awk '{$1=\"\"}1' 'data2.dat' | sed '1 d'" matrix every 2::1 w image, \
'' matrix using ($1+1):2:(sprintf('%d', $3)) every 2 with labels
I want to remove the palette because I adjust the ploting colors by percentage of my data. So, I guess the palette on the right my table is now use anymore. Thanks
That is the colorbox. Just use
unset colorbox
to remove it.

Resources