Search code examples
gnuplotconvex-hull

Conditional plotting with table & convexhull


Giving these data (datos.txt)

0   23      -0.3    26/11/2023 14:45:00
0   23.1    -0.3    26/11/2023 13:45:00
0   23.2     0      11/02/2023 18:15:00
0   24      -0.6    26/11/2023 15:15:00
0   25      -0.2    26/11/2023 13:15:00
0   26       0      11/02/2023 11:15:00
0   27      -0.3    26/11/2023 16:15:00
0   28      -0.1    26/11/2023 12:45:00
0   29       0      11/02/2023 10:45:00
0   30      -0.2    30/10/2022 16:15:00
0   32       0      12/02/2023 18:15:00
0   32.1    -0.3    26/11/2023 11:45:00
0   33      -0.7    18/12/2023 13:15:00
0   34       0.1    12/06/2022 08:15:00
0   34.1     0.6    30/10/2022 16:45:00
0   34.2     0.3    12/05/2024 21:45:00
0   36      -0.3    26/11/2023 11:15:00
0   37      -0.5    28/01/2024 11:45:00
0   37.1    -0.4    22/01/2024 11:15:00
0   37.2    -0.2    31/10/2022 15:45:00
0   37.3    -0.3    12/01/2024 03:45:00
0   37.4    -0.5    18/12/2023 12:45:00
0   38      -0.7    29/10/2022 12:15:00
0   38.1    -0.2    22/03/2024 20:15:00
0   39      -1.4    19/12/2023 15:45:00
0   39.1     0.3    29/03/2023 09:45:00

and this script

reset session
set table $HULL                                                                                
plot "datos.txt" u (gprintf("%.1f",$1)):(($3)>0.2 && ($3)<0.7 ? (gprintf("%.f",$2)): NaN) w table convexhull                     
unset table                                                                                
print $HULL

I obtain the following result

0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0     34
0.0     34
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0      nan
0.0     39

Is there a way to dump only the non-nan rows into the $HULL file ? without table it is possible but then I'm not allowed to use explicit format for x & y columns.


Solution

  • As I understand your question, you want to plot a convex hull, but only from a set of filtered points (depending on a 3rd column) and get the x,y data in a custom format into a table.

    Although, Ethan basically answered your question and already mentioned that you need to do it in two passes, let me give an illustrative example.

    The options convexhull and if and with table do not work together. Hence:

    • combine convexhull together with a ternary filter in the y-column (not using table and if options)

    The data in $HULL in the example below will look like this:

    # Curve 0 of 1, 10 points
    # x y type
    -1.726 -0.494  i
    -1.192 1.257  i
    -0.493 1.711  i
    1.982 0.274  i
    2.456 -0.273  i
    0.811 -1.694  i
    -0.208 -2.535  i
    -0.604 -2.391  i
    -1.014 -1.824  i
    -1.726 -0.494  i
    

    If you are not happy with the headers and the extra i column, get the desired format into $HULL2 via sprintf() and with table by adding the lines:

    set table $HULL2
        plot $HULL u (sprintf("%.3f %.3f", $1, $2)) w table
    unset table
    print $HULL2
    

    And $HULL2 will look like this:

    -1.726 -0.494
    -1.192 1.257
    -0.493 1.711
    1.982 0.274
    2.456 -0.273
    0.811 -1.694
    -0.208 -2.535
    -0.604 -2.391
    -1.014 -1.824
    -1.726 -0.494
    

    In order to illustrate:

    • The convexhull will be created only from the "green" points where the values of column 3 are inbetween cmin=0.2 and cmax=0.7.
    • the table $HULL2 contains the data in the desired format (here: "%.3f")

    Script: (requires gnuplot>=6.0.0, because of convexhull)

    ### create custom formatted table of convex hull of filtered datapoints
    reset session
    
    # create some random test data
    set table $Data
        plot '+' u (invnorm(rand(0))):(invnorm(rand(0))):(rand(0)) w table
    unset table
    
    set offsets 0.1,0.1,0.1,0.1
    set key noautotitle
    
    cmin = 0.2
    cmax = 0.7
    set palette defined (0 "red", cmin "red", cmin "green", cmax "green", cmax "red", 1.0 "red")
    
    set table $HULL
        set format x "%.3f"
        set format y "%.3f"
        plot $Data u 1:(($3>cmin && $3<cmax) ? $2 : NaN) convexhull
    unset table
    print $HULL
    
    set table $HULL2
        plot $HULL u (sprintf("%.3f %.3f", $1, $2)) w table
    unset table
    print $HULL2
    
    set format x "%h"   # restore default in case you changed it above
    set format y "%h"
    
    plot $HULL u 1:2 w lp pt 6 ps 2 pi -1 lc "black", \
         $Data u 1:2:3 w p pt 7 lc palette z
    ### end of script
    

    Result:

    enter image description here