Search code examples
gnuplot

Gnuplot: making a vertical calendar with weeks aligned


I'm trying to make a vertical calendar in gnuplot with the rows aligned by weeks. I already have it in horizontal, thanks to this thread. However, now I would like to make a vertical version because it fits better for my needs.

This is the code:

reset session

myTimeFmt  = '%d/%m/%Y'
DateStart  = '01/01/2023'
DateEnd    = '31/12/2023'
SecsPerDay = 24*3600

set print $Data
    do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
        print strftime(myTimeFmt,t)
    }
set print

set xtics 1 scale 0 offset 0,0.20 font 'Times, 12'
set x2tics 1 scale 0 offset 0,-0.20 font 'Times, 12'
set ytics 1 scale 0 font 'Times, 12'
set y2tics 1 out scale 0 font 'Times, 12'
set yrange [:] reverse noextend
set key noautotitle
set style fill solid 1 border lc '#A3ACB7'
set border lc rgb '#A3ACB7'
set lmargin 5
set rmargin 5
set bmargin 2.5
set tmargin 2

# y=0 only month, y=1 month+year
Month(t)        = int(tm_year(t)*12 + tm_mon(t))
MonthLabel(t,y) = strftime( y=0 ? '%b %Y' : '%b', t)
WeekDay(t)      = strftime('%a',t)[1:1]
DayColor(t)     = tm_wday(t) == 0 ? 0x284a64 : tm_wday(t) == 6 ? 0x1d374b : 0x1b222a
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))

plot $Data u \
    (Month(t)):\
    (t=timecolumn(1,myTimeFmt), tm_mday(t)+MonthOffset(t)):\
    (0.5):\
    (0.5):\
    (DayColor(t)):\
    ytic(WeekDay(t)):\
    xtic(MonthLabel(t,1)):\
    x2tic(MonthLabel(t,1)):\
    y2tic(WeekDay(t)) w boxxy lc rgb var

The result is the following:

enter image description here

As you can see, some rows appear displaced to the right. And the labels for the months are also displaced (January is missing, while December appears twice). These are the two little errors I'm having.

For example, the first day of May is ok, then it has some days moved to the right.


Solution

  • I'm not sure (yet) what exactly is causing the shifts in your script. In principle, you simply have to swap x and y, i.e. x,y-columns and xtic() and ytic() labels. I took the original script you linked to and did that below (plus correcting a typo: "%b" instead of "%Y", which you already corrected in your script).

    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 [*:*]
    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" : "%b", t)   # y=1 month+year, y=0 only month
    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), Month(t)):(tm_mday(t)+MonthOffset(t)):(0.5):(0.5):(DayColor(t)): \
                 ytic(WeekDay(t)):y2tic(WeekDay(t)):xtic(MonthLabel(t,0)):x2tic(MonthLabel(t,0)) w boxxy lc rgb var, \
            '' u (t=timecolumn(1,myTimeFmt), Month(t)):(tm_mday(t)+MonthOffset(t)):(sprintf("%d",tm_mday(t))) w labels font ",8"
    ### end of script
    

    Result:

    When checking the output I was just a bit confused, because I generated a calendar for 2022 (not 2023).

    enter image description here