0

I'm making a weather display graph using GNUplot with a weather API. I'm currently plotting the next 48 hours of temperature and rainfall.

enter image description here

As you can see in the above image, the temperature is the line with the axis defined on the left; while the rainfall is depicted by the bar graph (bottom left) and its axis is defined on the right. (0, 0.5, 1).

I would however like to include other data in the graph as well. The first thing I want to include is cloud cover at the top of the graph. Again as a bar graph.

I'm including a mockup that I made is a graphic editor:

enter image description here

Is there a way to do this with gnuplot, or will I have to use another program to accomplish it?

Jim
  • 2,243
  • 2
  • 13
  • 17

1 Answers1

3

You have y1-axis on the left and y2-axis on the right. If you want to have a 3rd y-axis you have to shift it somehow. One way to achieve this is with multiplot, basically several plots on top of each other. You have to make sure that all plots are using the same (fixed) margins on the canvas (automargin probably won't work) and the same xrange (the second plot takes it from the first plot). Check the following example with some random data. Certainly, some fine tuning could be done. Adapt it to your needs.

Code:

### Three y-axes
reset session

# create some test data
myTimeFmt = "%d.%m.%Y %H:%M:%S"
set print $Data
    do for [i=1:48] {
        myTime(i) = strftime(myTimeFmt, time(0)+i*3600)
        myTemp(i) = sin(i/5.)*5 + 20 + rand(0)
        myRain(i) = int(rand(0)+0.3) * rand(0)*20
        myCloud(i) = rand(0)*50
        print sprintf("%s %g %g %g",myTime(i),myTemp(i),myRain(i),myCloud(i))
    }
set print

set key off
set margins screen 0.1, screen 0.8, screen 0.1, screen 0.94

set multiplot
    set format x "%H:%M" timedate
    set xtics 3600*6
    set grid xtics, mxtics, ytics, mytics
    
    ##### first plot
    set ylabel "Temperature °C" tc "red"
    set yrange[10:30]
    set ytics nomirror tc "red"

    set y2label "Rain / mm" offset -1,0 textcolor rgb "blue"
    set y2range[0:40]
    set y2tics nomirror tc "blue"

    set style fill solid 1.0 
    plot $Data u (timecolumn(1,myTimeFmt)):3 axes x1y1 w l lc "red", \
        '' using (timecolumn(1,myTimeFmt)):4 axes x1y2 w boxes lc "blue"

    unset xlabel 
    unset ylabel
    unset y2label
    unset tics

    ##### Second plot
    set bmargin screen 0.73
    set border 4
    set xrange[GPVAL_X_MIN:GPVAL_X_MAX]    # identical xrange like 1st plot
    set y2range[100:0] reverse
    plot $Data u (timecolumn(1,myTimeFmt)):5 axes x1y2 w boxes lc rgbcolor "grey"

    ##### Third plot (just for 3rd y-axis)
    set rmargin at screen 0.9
    set border 8     # only right border visible
    set y2label "Cloud coverage" offset -1,0 textcolor rgb "black"
    set y2tics nomirror offset 0,0
    plot NaN    # plot some dummy

unset multiplot
### end of code

Result:

enter image description here

theozh
  • 22,244
  • 5
  • 28
  • 72
  • This looks great! I started building the 3rd axis on a transparent PNG with the intention of compositing the transparent PNG over the original, but as there were different labels, it was proving to not overlay properly. I will go over your answer in more detail when I have a moment soon. – Jim Sep 08 '20 at 04:42
  • Thanks @Theozh. While I had many other requirements that were not pivotal to the base question; your answer didn't really work for my purposes. HOWEVER, having said that, I used your answer to guide me to the answer I needed. So thank you! Also, As the answer you provided did indeed answer the question that I asked correctly, I've marked it as such. – Jim Sep 09 '20 at 09:58