Search code examples
command-linegnuplotmultiple-axes

Is there a way to have 3 different Y axes on one graph using gnuplot?


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?


Solution

  • 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