gnuplot - splot inline data and point labels - gnuplot

Hi Im using this data to get a 3d/2d like histogram.
I want to label each histogram column with a 'dx cx' label preferable on top of the column.
With my example the graph is drawing correctly, but there are no labels. if I'm using only the using 1:2:3:4 with labels offset 1 part, it shows the label with no lines. And it only shows the label to the space character, can I somehow escape the space?
Could anyone help please?
reset
unset key
set xrange [0:262.5]
set yrange [0:350]
set zrange [0:5]
set xtics 50
set ytics 50 offset .6,-.3
set ztics 1,1
set grid x y z back
set xyplane 0
set terminal pdf
set output "test.pdf"
splot '-' using 1:2:3 with lines, '' using 1:2:3:4 with labels offset 1
27.8409 350 0
27.8409 350 0.419595 d0 c3
31.8182 350 0.419595
31.8182 350 0
31.8182 350 0
31.8182 350 0.61032 d0 c4
35.7955 350 0.61032
35.7955 350 0
35.7955 350 0
35.7955 350 0.740013 d0 c5
39.7727 350 0.740013
39.7727 350 0
39.7727 350 0
39.7727 350 0.747642 d0 c6
43.75 350 0.747642
43.75 350 0
43.75 350 0
43.75 350 0.633207 d1 c1
47.7273 350 0.633207
47.7273 350 0
47.7273 350 0
47.7273 350 0.442482 d1 c2
51.7045 350 0.442482
51.7045 350 0
e

Your second plot is never done. The inline data is gone after the first part. You have to feed it twice (same dataset again after the "e") or in gp5 you can use a new form of inline data:
$data << EOD
1 2 3
2 3 4
3 4 5
EOD
splot $data, $data using 1:2:($2**2)
If the data comes in via stdin ("-"), you can use set table to plot it to a temporary file or to an inline data set set table $dat; plot "-"; unset table.

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

gnuplot splot approximation or interpolation?

I'm rendering heat map using gnuplot splot with pm3d using next script
set view map
set dgrid3d
set pm3d interpolate 20,20
set palette defined(\
0 '#00dc00',\
3640 '#00ff00',\
32767 '#c8ff00',\
61894 '#ff8000',\
65535 '#ff7000')
splot "d:/source.dat" using 1:2:3 with pm3d
"source.dat" file contains next values
0 0 36
1 0 36
2 0 36
0 1 36
1 1 36
2 1 36
0 2 36
1 2 36.9
2 2 36
Gnuplot produced next image
But I'm not understand why I have red color in top center point which is equals to 36.6 temperature according to the pallete. In data file I have 36.9 instead of that. It seems to me that gnuplot approximated this value. How I could configure in to interpolate all points?

Plotting a histogram, wrong alignment of bars and labelling

I'm having trouble with a gnuplot, somehow the x labelling shifts to the right (or the bars to the left) when defining
set style data histograms
The Plotscript:
set boxwidth 0.9 absolute
set style fill solid 1.00 border lt -1
set key inside left top vertical Right noreverse noenhanced autotitles nobox
set style histogram clustered gap 5 title offset character 0, 0, 0
set datafile missing '-'
set style data histograms
set xtics border in scale 0,0 nomirror rotate by -45 offset character 0, 0, 0
set xtics norangelimit font ",8"
set xlabel "Scaling Factor"
set ylabel "Execution time [ms]"
set title "Database performance db4o vs Sqlite - Testcase 1 [indexed]"
set logscale y
set terminal pdf
set output 'db4o_vs_sqlite_indexed.pdf'
plot 'db4o_sb1-5idx.dat' using 3:xtic(1) title 'db4o', 'sqlite_sb1-5idx.dat' using 3 title 'Sqlite'
The data:
"Scaling Factor" "Testcase 1" "Testcase 2" "Testcase 3" "Testcase 4"
1 0 34 28 11
2 1 136 91 65
3 0 297 198 101
4 0 487 297 214
10 0 3124 1896 1567
20 0 13000 7907 7628

in gnuplot how do i set a key (legend) when using "plot with labels"

When I use "plot with labels" with various groups of points everything is ok, labels appear in different colors.
However I could not find a way to set the key (legend) properly I would like to have a sample of the text color used for each group of points. All a get is the title associated to each group.
set term x11
set key outside
set grid
set xlabel "#occurences"
set ylabel "F-score"
set title "Experiment"
plot "-" lw 1 with labels font "\"Helvetica\"" tc lt 1 title "foo" , "-" lw 1 with labels font "\"Helvetica\"" tc lt 2 title "bar"
96.0 0.24390244 11
5547.0 0.7443704 24
3974.0 0.83244646 114
241.0 0.16025642 174
6220.0 0.7571273 188
7810.0 0.8637012 206
e
98.0 0.0 4
96.0 0.11320755 11
5547.0 0.75145125 24
3974.0 0.8333118 114
6220.0 0.7646692 188
7810.0 0.87222874 206
e
That is done with set key textcolor variable, as stated in the comments:
set key outside textcolor variable
set grid
set xlabel "#occurences"
set ylabel "F-score"
set title "Experiment"
plot "-" lw 1 with labels font "\"Helvetica\"" tc lt 1 title "foo" , "-" lw 1 with labels font "\"Helvetica\"" tc lt 2 title "bar"
96.0 0.24390244 11
5547.0 0.7443704 24
3974.0 0.83244646 114
241.0 0.16025642 174
6220.0 0.7571273 188
7810.0 0.8637012 206
e
98.0 0.0 4
96.0 0.11320755 11
5547.0 0.75145125 24
3974.0 0.8333118 114
6220.0 0.7646692 188
7810.0 0.87222874 206
e
Result with 4.6.5:

Resources