Indicating weekends in timeseries plot and setting xrange in timeseries gnuplot - gnuplot

Using the excellent answer gnuplot - Read Double Quoted datetime stamp I have been able to plot my time series data.
I now trying to indicate weekends (or interesting timeblocks) my plot and set visible xrange to be 31/1 to 28/2
Weekends in Feb this year were 2/5/22 to 2/6/22 and 2/12/22 to 2/13/22 etc - how could I draw a vertical column and shade to indicate weekend or other interesting timeseries blocks? I looked at trying to plot a rectangle using timeseries points, ie weekend1, but I was unable to fill that shape. Then I tried to draw a rectangle, but could not work out how to specify the corners in the timeseries format to display it.
Since my x axis is a timeseries
How could I indicate all weekends in the diagram - kind of like in a calendar or timesheet?
How do I define the xrange to be 1/31/22 to 2/28/22?
reset session
set datafile separator comma
myTimeFmt = "%m/%d/%y, %H:%M %p"
set format x "%d" time
#
# Gives error all points y value undefined!
#
# set xrange ["1/31/22, 12:01 AM":"2/28/22, 11:59 PM"] #
#
# Trying to draw a series to fill to indicate a weekend range - vertically
#
$weekend1 <<EOD
"2/5/22, 12:01 AM",0
"2/5/22, 12:01 AM",600
"2/6/22, 11:59 PM",600
"2/6/22, 11:59 PM",0
EOD
$account <<EOD
"1/31/22, 5:07 PM",1
"1/31/22, 8:01 PM",100
"2/1/22, 11:10 AM",200
"2/6/22, 12:25 PM",300
"2/9/22, 2:02 PM",400
"2/24/22, 4:22 PM",500
EOD
set object 1 rect from 1,1 to 2,2
plot $account u (timecolumn(1,myTimeFmt)):2 w lp pt 1 ps 1 lc "red" lw 1 ti "Account"
#plot $weekend1 u (timecolumn(1,myTimeFmt)):2 w lp pt 1 ps 1 lc "grey"

Here is what I've understood from your question: plot some time series data and highlight the weekends by coloring the background.
One possible way to get this would be to create datablock with all days within your time range and draw boxes (check help boxxyerror) which are colored (check help lc variable) depending of the weekday (check help tm_wday).
first you have to plot the boxes in the background and then the data
the background color should span the whole vertical graph size. For this you need to know the y-range of the data. You can get STATS_min and STATS_max from stats (check help stats).
in order to span the whole graph you can extend the y-range of the boxes (by adding the range again on top and on bottom) but do not apply autoscale for the boxes (check help noautoscale). Autoscale will be only used for the data.
Maybe you have a fixed known y-range, then you can simply set it via set yrange and suitable size of the boxes.
I hope you can adapt the following example to your needs.
Script:
### highlight weekends
reset session
myTimeFmt = "%d.%m.%Y"
DateStart = "01.01.2022"
DateEnd = "28.02.2022"
SecsPerDay = 24*3600
# create some random test data
set print $Data
y=50
do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
print sprintf('"%s", %g', strftime(myTimeFmt,t),y=y+rand(0)*10-5)
}
set print
# datablock with every day between start and end date
set print $Days
do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
print strftime(myTimeFmt,t)
}
set print
set datafile separator comma
set key noautotitle
set style fill solid 0.4 border
set format x "%d %b\n%Y" timedate
set xtics out scale 2, 1
DayColor(t) = tm_wday(t)==0 ? 0xff0000 : tm_wday(t)==6 ? 0xffdd00 : 0xdddddd
stats $Data u 2 nooutput # get min and max from column 2
plot $Days u (t=timecolumn(1,myTimeFmt)):(0):(t):(t+SecsPerDay):\
(2*STATS_min-STATS_max):(2*STATS_max+STATS_min):(DayColor(t)) w boxxy lc rgb var noautoscale, \
$Data u (timecolumn(1,myTimeFmt)):2 w lp pt 7 lc "black"
### end of code
Result:
NB: first I thought you wanted to plot a calendar highlighting the weekends, but this was not your question. Since I already had the following code (which will plot a calendar in two different versions), I will post it nevertheless. Maybe it is useful to you or others for further adaptions and optimizations.
Script:
### plot a calendar
reset session
myTimeFmt = "%d.%m.%Y"
DateStart = "01.01.2022"
DateEnd = "31.12.2022"
SecsPerDay = 24*3600
set print $Calendar
do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
print strftime(myTimeFmt,t)
}
set print
set xrange[0.5:31.5]
set xtics 1 scale 0 offset 0,0.5 font ",8"
set link x2 via x inverse x
set x2tics 1 out scale 0 offset 0,-0.5 font ",8"
set yrange [:] reverse noextend
set ytics 1 scale 0
set key noautotitle
set style fill solid 0.4 border lc "black"
WeekDay(t) = strftime("%a",t)[1:1]
DayColor(t) = tm_wday(t) == 0 ? 0xff0000 : tm_wday(t) == 6 ? 0xffdd00 : 0xdddddd
Month(t) = int(tm_year(t)*12 + tm_mon(t))
MonthLabel(t,y) = strftime( y ? "%B %Y" : "%Y", t) # y=0 only month, y=1 month+year
plot $Calendar u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5):(DayColor(t)): \
xtic(tm_mday(t)):ytic(MonthLabel(t,1)) w boxxy lc rgb var, \
'' u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(WeekDay(t)) w labels
pause -1
MonthFirst(t) = int(strptime("%Y%m%d",sprintf("%04d%02d01",tm_year(t),tm_mon(t)+1)))
MonthOffset(t) = tm_wday(MonthFirst(t))==0 ? 7 : tm_wday(MonthFirst(t))
set xrange[*:*]
plot $Calendar u (t=timecolumn(1,myTimeFmt), tm_mday(t)+MonthOffset(t)):(Month(t)):(0.5):(0.5):(DayColor(t)): \
xtic(WeekDay(t)):x2tic(WeekDay(t)):ytic(MonthLabel(t,1)) w boxxy lc rgb var, \
'' u (t=timecolumn(1,myTimeFmt), tm_mday(t)+MonthOffset(t)):(Month(t)):(sprintf("%d",tm_mday(t))) w labels font ",8"
### end of script
Result:
Addition: (calendar with events from a datafile/datablock)
Script:
### plot a calendar with events
reset session
myTimeFmt = "%d.%m.%Y"
DateStart = "01.01.2022"
DateEnd = "31.12.2022"
SecsPerDay = 24*3600
set print $Calendar
do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
print strftime(myTimeFmt,t)
}
set print
$Events <<EOD
01.01.2022 A 0xff0000
23.04.2022 B 0x00ff00
03.06.2022 C 0x0000ff
12.08.2022 A 0xffff00
05.09.2022 B 0xff00ff
10.10.2022 X 0x00ffff
12.02.2022 Y 0xffa500
EOD
set xrange[0.5:31.5]
set xtics 1 scale 0 offset 0,0.5 font ",8"
set link x2 via x inverse x
set x2tics 1 out scale 0 offset 0,-0.5 font ",8"
set yrange [:] reverse noextend
set ytics 1 scale 0
set key noautotitle
set style fill solid 0.4 border lc "black"
Month(t) = int(tm_year(t)*12 + tm_mon(t))
MonthLabel(t,y) = strftime( y ? "%B %Y" : "%Y", t) # y=0 only month, y=1 month+year
plot $Calendar u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5): \
xtic(tm_mday(t)):ytic(MonthLabel(t,1)) w boxxy lc "light-grey", \
$Events u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5):3 w boxxy lc rgb var, \
'' u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):2 w labels
### end of script
Result:

Related

Gnuplot multi column plot using CSV headings

I'm struggling to get a multi-column bar chart / histogram going with my input as a CSV with headings. As well as the key showing the {wcfiles,wclines,clocfiles,cloclines} attributes.
$summary << EOD
browser,wcfiles,wclines,clocfiles,cloclines
webkitgtk-2.28.2,19472,4710385,18620,3120740
firefox-78.0.1,289298,43627834,240137,24371602
chromium-83.0.4103.116,420343,100340817,269434,49597826
EOD
set datafile separator ','
set yrange [0:*] # start at zero, find max from the data
set style fill solid border -1
set ytics format "%.0s%c" # will generate labels 100k 200k 300k ... 1M
set title 'sloc the Web'
plot '$summary' using 0:2:($0+1):xtic(1) with boxes lc variable,\
"" u 3 title "wclines",\
"" u 4 title "clocfiles"
Check the examples #Ethan mentioned.
In your case you should set logscale y, otherwise it will be difficult to visualize values with differences of several orders of magnitude.
Code:
### histogram clustered
reset session
$Data <<EOD
browser,wcfiles,wclines,clocfiles,cloclines
webkitgtk-2.28.2,19472,4710385,18620,3120740
firefox-78.0.1,289298,43627834,240137,24371602
chromium-83.0.4103.116,420343,100340817,269434,49597826
EOD
set datafile separator ','
set title 'sloc the Web'
set yrange [1000:*]
set logscale y
set ytics format "%.0s%c"
set style data histogram
set style histogram cluster gap 1
set style fill solid border -1
set boxwidth 0.9
plot $Data u 2:xtic(1) ti col,\
'' u 3 ti col,\
'' u 4 ti col
### end of code
Result:

How to display y-labels on top of histogram bars on gnuplot

I desgined a histogram in gnuplot however the y-scale needs to be in log2 due to huge difference in values. Therefore, to improve readability of the plot I pretend to display the concrete values on top of each bar. The values represent bytes and so I would like for this values also be in log2 and to be formated to display kb, Mb, ... as is being done in the y-axis.
How can I achieve this?
This is the comands I'm currently using:
set terminal postscript eps enhanced dash color "" 13
reset
set datafile separator ","
set title "Bytes per Protocol"
set xlabel "Protocol"
set ylabel "Bytes" rotate by 90
set yrange [0:1342177280]
set logscale y 2
set format y '%.0s%cB'
set style data histogram
set boxwidth 0.5
set style fill solid
set xtics format ""
set grid ytics
set style data histogram
set style histogram clustered gap 2
set grid ytics
set tic scale 0
set size 1,0.9
set size ratio 0.5
set key autotitle columnhead
set output "ex_a_1_BIG.eps"
plot "ex_a_1_BIG.csv" using ($3):xtic(1) title "IN", \
'' using ($5):xtic(1) title "OUT", \
'' using 0:($3):($3) with labels center offset -2,1 notitle, \
'' using 0:($5):($5) with labels center offset 2,1 notitle
This is the content of the csv I want to plot (I only want the bytes in and out):
protocol,packets in,bytes in,packets out,bytes out
ICMP,1833,141562,979,60334
IGMP,0,0,283,14006
TCP,158214,129221151,130101,47734355
UDP,68476,9571677,72530,24310734
Check help format_specifiers and help gprintf. And the example below.
What is a bit unfortunate, that in gnuplot apparently the prefix for 1 to 999 is a single space instead of an empty string.
For example, with the format '%.1s %cB' this leads to two spaces for 1-999 B and one space for the others, e.g. 1 kB. However, if you use '%.1s%cB' this leads to one space for 1-999 B and no space for the others e.g. 100kB. As far as I know, correct would be one space between the number and the units. I'm not sure whether there is an easy fix for this.
Code:
### prefixes
reset session
$Data <<EOD
1 1
2 12
3 123
4 1234
5 12345
6 123456
7 1234567
8 12345678
9 123456789
10 1234567890
11 12345678901
12 123456789012
13 1234567890123
EOD
set boxwidth 0.7
set style fill solid 1.0
set xtics 1
set yrange [0.5:8e13]
set multiplot layout 2,1
set logscale y # base of 10
set format y '%.0s %cB'
plot $Data u 1:2 w boxes lc rgb "green" notitle, \
'' u 1:2:(gprintf('%.1s %cB',$2)) w labels offset 0,1 not
set logscale y 2 # base of 2
set format y '%.0b %BB'
plot $Data u 1:2 w boxes lc rgb "red" notitle, \
'' u 1:2:(gprintf('%.1b %BB',$2)) w labels offset 0,1 not
unset multiplot
### end of code
Result:
Addition:
a workaround for number/unit space issue at least for the labels in the graph would be:
myFmt(c) = column(c)>=1 && column(c)<1000 ? \
gprintf('%.1s%cB',column(c)) : gprintf('%.1s %cB',column(c))
and
plot $Data u 1:2 w boxes lc rgb "green" notitle, \
'' u 1:2:(myFmt(2)) w labels offset 0,1 not
But for the ytics labels I still don't have an idea.

Plot a forecast line with Gnuplot?

I've this data :
Serv1;2019-10;2561.36
Serv1;2019-11;3292.65
Serv1;2019-12;3077.58
Serv1;2020-01;3369.98
Serv1;2020-02;3134.53
Serv1;2020-03;593.332
With excel, I'm able to create an graph with a forecast line on excel like that :
I'm able to create a graph with gnuplot :
With this gnuplot script :
set title "test"
set terminal png truecolor size 960,720 background rgb "#eff1f0"
set output "/xxx/xxx/xxx/xxx/xxx/test.png"
set grid
set style line 1 \
linecolor rgb '#0060ad' \
linetype 1 linewidth 2 \
pointtype 7 pointsize 1.5
set offsets 0.5,0.5,0,0.5
set datafile separator ";"
set key left
plot "test.txt" using 3:xtic(2) with linespoints linestyle 1
But I don't know how to plot a forecast line with Gnuplot...
Could you show me how to do that ?
Assuming you are looking for a linear fit and extending this linear function, you can try the following below.
Edit:
There is no gnuplot function to get the data value of a certain row and column, e.g. like a = value(row,column). You have to use a somehow strange workaround. Basically, you plot your data into a dummy table, but only the first datapoint of the first block of the first dataset (counting starts with 0). Check help every and help index.
set table $Dummy
plot $Data u (StartDate=timecolumn(1,myTimeFmt)) index 0 every ::0:0:0:0 w table
unset table
print sprintf("StartDate: %s",strftime(myTimeFmt,StartDate))
Result: StartDate: 01/03/2020
Code:
### linear fit and extrapolation
reset session
$Data <<EOD
01/03/2020,100
02/03/2020,150
03/03/2020,125
04/03/2020,150
05/03/2020,175
06/03/2020,200
07/03/2020,220
08/03/2020,150
09/03/2020,175
10/03/2020,125
11/03/2020,150
12/03/2020,200
13/03/2020,210
14/03/2020,230
EOD
set datafile separator comma
myTimeFmt = "%d/%m/%Y"
set format x "%d.%m." time
# put start date into variable StartDate
set table $Dummy
plot $Data u (StartDate=timecolumn(1,myTimeFmt)) index 0 every ::0:0:0:0 w table
unset table
EndDate = strptime("%Y-%m","30/04/2020")
f(x) = a*(x-StartDate)+ b
set fit quiet nolog
fit f(x) $Data u (timecolumn(1,myTimeFmt)):2 via a,b
set xrange[StartDate:EndDate]
set grid xtics, ytics
plot $Data u (timecolumn(1,myTimeFmt)):2 w lp pt 7 lc rgb "red" notitle, \
[StartDate:EndDate] f(x) ti "linear fit with extrapolation"
### end of code
Result:
Edit 2: (version for gnuplot 4.6)
Modified for gnuplot 4.6. Where I got problems and found out later is the parameter FIT_LIMIT = 1e-8 which you need to set for fitting timedata.
Data: (Data.dat)
Serv1;2019-10;2561.36
Serv1;2019-11;3292.65
Serv1;2019-12;3077.58
Serv1;2020-01;3369.98
Serv1;2020-02;3134.53
Serv1;2020-03;593.332
Code:
### linear fit and extrapolation, version for gnuplot 4.6
reset
FILE = "Data.dat"
set datafile separator ";"
set xdata time
set timefmt "%Y-%m"
set format x "%Y\n%m"
# put start date into variable StartDate, dummy plot
plot FILE u (StartDate=timecolumn(2)):0 index 0 every ::0:0:0:0
EndDate = strptime(myTimeFmt,"2020-09")
f(x) = a*(x-StartDate) + b
FIT_LIMIT = 1e-8
fit f(x) FILE u (timecolumn(2)):3 via a,b
set xrange[StartDate:EndDate]
set grid xtics, ytics
set yrange[0:4000]
plot FILE u (timecolumn(2)):3 w lp pt 7 lc rgb "red" notitle, \
f(x) ti "linear fit with extrapolation"
### end of code
Result:

Cumulative data and extrapolation with gnuplot

Having a list of dates and events which is not necessarily sorted by date
e.g. like
# Date Event
04.12.2018 -4
23.06.2018 5
04.10.2018 3
11.11.2018 -9
08.03.2018 -4
08.03.2018 2
11.11.2018 -3
I would like to sum up the events and do a (e.g. linear) extrapolation, e.g. when the data will hit a certain threshold (e.g. zero).
It looks like smooth frequency and smooth cumulative seemed to be made for this.
But I am struggeling with the following:
a) how can I add a start value (offset), e.g. StartValue = 500
plot $Data u (strftime("%d.%m.%Y",timecolumn(1,"%d.%m.%Y"))):($2+StartValue) smooth cumulative w l t "Cumulated Events"
doesn't do it.
b) how can I get the cumulative data? Especially if the data is not sorted by date?
set table "DataCumulative.dat"
plot $Data u (strftime("%d.%m.%Y",timecolumn(1,"%d.%m.%Y"))):2 smooth cumulative with table
unset table
This look similar to this question (GNUPLOT: saving data from smooth cumulative) but I don't get the expected numbers. In my example below in the file "DataCumulative.dat", I expected unique dates and basically the data from the lower plot. How to get this?
The code:
### start code
reset session
set colorsequence classic
# function for creating a random date between two dates
t(date_str) = strptime("%d.%m.%Y", date_str)
date_random(d0,d1) = strftime("%d.%m.%Y",rand(0)*(t(d1)-t(d0)) + t(d0))
# create some random date data
date_start = "01.01.2018"
date_end = "30.06.2018"
set print $Data
do for [i=1:1000] {
print sprintf("%s\t%g", date_random(date_start,date_end), floor(rand(0)*10-6))
}
set print
set xdata time
set timefmt "%d.%m.%Y"
set xtics format "%b"
set xrange[date_start:"31.12.2018"]
set multiplot layout 2,1
plot $Data u (strftime("%d.%m.%Y",timecolumn(1,"%d.%m.%Y"))):2 smooth frequency with impulses t "Events"
plot $Data u (strftime("%d.%m.%Y",timecolumn(1,"%d.%m.%Y"))):2 smooth cumulative w l t "Cumulated Events"
unset multiplot
# attempt to get cumulative data into datablock
set table "DataCumulative.dat"
plot $Data u (strftime("%d.%m.%Y",timecolumn(1,"%d.%m.%Y"))):2 smooth cumulative with table
unset table
### end of code
The plots:
I guess, I finally got it now. However, there are a few learnings which I still don't understand completely.
1.
In order to get the cumulative data you should not set
set table $DataCumulative
plot $Data u (stringcolumn(1)):2 smooth cumulative with table
unset table
but instead:
set table $DataCumulative
plot $Data u (stringcolumn(1)):2 smooth cumulative
unset table
note the missing "with table" in the plot command.
The first version gives you the original data, the second one the desired cumulative data. But I don't yet understand why.
2.
the default datafile separator setting
which is
set datafile separator whitespace
it doesn't seem not to work. It will give an error message like line xxx: No data to fit
instead, you have to set
set datafile separator " \t" # space and TAB
But I don't understand why.
3.
fitting time date
f_lin(x) = m*x + c
won't give a good fit at all. Apparently, you have to subtract the start date and do the fitting.
f_lin(x) = m*(x-strptime("%d.%m.%Y", Date_Start)) + c
I remember reading this long time ago in the gnuplot documention but I can't find it anymore.
For the time being, I am happy now with the following.
The modified code:
### generate random date between two dates
reset session
# function for creating a random date between two dates
t(date_str) = strptime("%d.%m.%Y", date_str)
date_random(d0,d1) = strftime("%d.%m.%Y",rand(0)*(t(d1)-t(d0)) + t(d0))
# create some random date data
Date_Start = "01.01.2018"
Date_End = "30.06.2018"
set print $Data
do for [i=1:100] {
print sprintf("%s\t%g", date_random(Date_Start,Date_End), floor(rand(0)*10-6))
}
set print
set xdata time
set timefmt "%d.%m.%Y"
# get cumulative data into datablock
set xtics format "%d.%m.%Y"
set table $DataCumulative
plot $Data u (stringcolumn(1)):2 smooth cumulative
unset table
set xtics format "%b"
set datafile separator " \t" # space and TAB
# linear function and fitting
f_lin(x) = m*(x-strptime("%d.%m.%Y", Date_Start)) + c
set fit nolog quiet
fit f_lin(x) $DataCumulative u 1:2 via m,c
Level_Start = 500
Level_End = 0
x0 = (Level_End - Level_Start - c)/m + strptime("%d.%m.%Y", Date_Start)
set multiplot layout 3,1
# event plot & cumulative plot
set xrange[Date_Start:"31.12.2018"]
set xtics format ""
set lmargin 7
set bmargin 0
plot $Data u (timecolumn(1,"%d.%m.%Y")):2 smooth frequency with impulses lc rgb "red" t "Events 2018"
set xtics format "%b"
set bmargin
plot $Data u (timecolumn(1,"%d.%m.%Y")):2 smooth cumulative w l lc rgb "web-green" t "Cumulated Events 2018"
# fit & extrapolation plot
set label 1 at x0, graph 0.8 strftime("%d.%m.%Y",x0) center
set arrow 1 from x0, graph 0.7 to x0, Level_End
set key at graph 0.30, graph 0.55
set xrange[Date_Start:x0+3600*24*50] # end range = extrapolated date + 50 days
set xtics format "%m.%y"
set yrange [-90:]
plot $DataCumulative u (timecolumn(1,"%d.%m.%Y")):($2+Level_Start) w l lc rgb "blue" t "Cumulated Events",\
Level_End w l lc rgb "red" not,\
f_lin(x)+Level_Start w l ls 0 t "Fitting \\& Extrapolation"
unset multiplot
### end of code
will result in:

GNUPLOT - Two columns histogram with values on top of bars

yesteraday I made a similar question (this one). I could not display the value on top of bar in a gnuplot histogram. I lost many time because I couldn't find really good documentation about it, and I only can find similar issues on differents websites.
I lost many time with that but fortunately someone give me the solution. Now I am having a similar issue with an histogram with two bars, in which I have to put on top of both bars its value. I am quite near, or that is what I think, but I can't make it work properly. I am changing the script and regenerating the graph many times but I am not sure of what I am doing.
script.sh
#!/usr/bin/gnuplot
set term postscript
set terminal pngcairo nocrop enhanced size 600,400 font "Siemens Sans,8"
set termoption dash
set output salida
set boxwidth 0.8 absolute
set border 1
set style fill solid 1.00 border lt -1
set key off
set style histogram clustered gap 1 title textcolor lt -1
set datafile missing '-'
set style data histograms
set xtics border in scale 0,0 nomirror autojustify
set xtics norangelimit
set xtics ()
unset ytics
set title titulo font 'Siemens Sans-Bold,20'
set yrange [0.0000 : limite1] noreverse nowriteback
set y2range [0.0000 : limite2] noreverse nowriteback
show style line
set style line 1 lt 1 lc rgb color1 lw 1
set style line 2 lt 1 lc rgb color2 lw 1
## Last datafile plotted: "immigration.dat"
plot fuente using 2:xtic(1) ls 1 ti col axis x1y1, '' u 3 ls 2 ti col axis x1y2, '' u 0:2:2 with labels offset -3,1 , '' u 0:2:3 with labels offset 3,1
I am modifying the last code line, because is here where I set the labels. I have been able to show both labels, but in bad positions, I have also been able to show one of the labels in the right position but no the other. I have been able to show almost everything but the thing that I want. This is the graph that generates the script.
output.png
This is the source file that I use for generating the graph
source.dat
"Momento" "Torre 1" "Torre 2"
"May-16" 1500.8 787.8
"Jun-16" 1462.3 764.1
"Jul-16" 1311.2 615.4
"Ago-16" 1199.0 562.0
"Sep-16" 1480.0 713.8
"Oct-16" 1435.1 707.8
And that's the command that I execute with the parameters set
gnuplot -e "titulo='Energía consumida por torre (MWh)'; salida='output.png'; fuente='source.dat'; color1='#FF420E'; color2='#3465A4'; limite1='1800.96'; limite2='945.36'" script.sh
I think that is quite obvious what I am pretending, can someone help me?
Lots of thanks in advance.
Your script has several problems, the missing ti col is only one of them. (You can also use set key auto columnheader, then you must not give that option every time).
Don't use both y1 and y2 axis if you want to compare the values! Otherwise the correct bar heights are only a matter of luck...
Understand, how gnuplot positions the histogram bars, then you can exactly locate the top center of each bar. If you only use offset with char values (which is the case when you give only numbers), then your script will break as soon as you add or remove a data row.
The histogram clusters start at x-position 0, and are positioned centered at integer x values. Since you have two bars in each cluster and a gap of 1, the center of the first bar is at ($0 - 1/6.0) (= 1/(2 * (numberOfTorres + gapCount))), the second one at ($0 + 1/6.0):
set terminal pngcairo nocrop enhanced size 600,400 font ",8"
set output 'output.png'
set title 'Energía consumida por torre (MWh)' font ",20"
set boxwidth 0.8 absolute
set border 1
set style fill solid 1.00 border lt -1
set style histogram clustered gap 1 title textcolor lt -1
set style data histograms
set xtics border scale 1,0 nomirror autojustify norangelimit
unset ytics
set key off auto columnheader
set yrange [0:*]
set offset 0,0,graph 0.05,0
set linetype 1 lc rgb '#FF420E'
set linetype 2 lc rgb '#3465A4'
# dx = 1/(2 * (numberOfTorres + gap))
dx = 1/6.0
plot 'source.dat' using 2:xtic(1),\
'' u 3,\
'' u ($0 - dx):2:2 with labels,\
'' u ($0 + dx):3:3 with labels
Now, starting at the bars center you can safely use offset to specify only the offset relative to the bars top center:
plot 'source.dat' using 2:xtic(1),\
'' u 3,\
'' u ($0 - dx):2:2 with labels offset -1,1 ,\
'' u ($0 + dx):3:3 with labels offset 1,1
A second option would be to use the label's alignment: The labels of the red bars are right aligned at the bars right border, the labels of the blue bars are left aligned at the bars left border:
absoluteBoxwidth = 0.8
dx = 1/6.0 * (1 - absoluteBoxwidth)/2.0
plot 'source.dat' using 2:xtic(1),\
'' u 3,\
'' u ($0 - dx):2:2 with labels right offset 0,1 ,\
'' u ($0 + dx):3:3 with labels left offset 0,1
In any case, both options make your script more robust against changes of the input data.
This looks better :
plot fuente using 3:xtic(1) ls 1 ti col axis x1y1, '' u 3 ls 2 ti col axis x1y2, '' u ($0-1):3:3 with labels offset -3,1 , '' u ($0-1):2:2 with labels offset 3,1
You had 2 plots commands: only the first one was displayed.
Also, script.sh should be a bash script. This is a gnuplot script, so it should have another extension.
The problem is the ti col tab. You need to put it in every option, including labels and not only in bars. The right code is:
plot fuente using 2:xtic(1) ls 1 ti col, '' u 3 ls 2 ti col, '' u 0:2:2 ti col with labels offset -3,1 , '' u 0:3:3 ti col with labels offset 3,1
And that's how the picture is displayed now:
You can also avoid ti col and that is how it would look:

Resources