Search code examples
plotdata-visualizationgnuplotheatmapdata-manipulation

gnuplot: plot 2d heatmap with non-integer pixel coordinates, with image pixels produces rotated 3D plot


I've been trying to plot a simple heatmap using the 'plot with image' but since my data is not in a perfect square shape it is not working properly.

A warning issuing "warning: Visible pixel grid has a scan line shorter than previous scan lines." continued popping up every time i moved the chart or zoomed it, while the 'with image pixels' version produced a version of the heatmap that was rotated in a 3D space (why was this the case if the 'with image' mode is for a 2D plot only?)

my data is:

0.9882380255806047 0.9882380255806047 -0.7703887858517308
0.9882380255806047 0.9929170035354357 -0.03247814980870606
0.9882380255806047 0.9975959814902666 -0.6944306255482046
0.9882380255806047 1.0022749594450977 -0.746165843927831
0.9882380255806047 1.0069539373999286 -0.5151139695781666
0.9882380255806047 1.0116329153547596 -0.1838806386646351
0.9929170035354357 0.9929170035354357 -0.7703887858517308
0.9929170035354357 0.9975959814902666 -0.9227715329230436
0.9929170035354357 1.0022749594450977 -0.9171361902702745
0.9929170035354357 1.0069539373999286 -0.7797704881116272
0.9929170035354357 1.0116329153547596 -0.6650103546953546
0.9975959814902666 0.9975959814902666 -0.7703887858517308
0.9975959814902666 1.0022749594450977 -0.9065086173718683
0.9975959814902666 1.0069539373999286 -0.3481667020388293
0.9975959814902666 1.0116329153547596 0.10123715036482903
1.0022749594450977 1.0022749594450977 -0.7703887858517308
1.0022749594450977 1.0069539373999286 -0.28406345548617745
1.0022749594450977 1.0116329153547596 0.1835875555217213
1.0069539373999286 1.0069539373999286 -0.7703887858517308
1.0069539373999286 1.0116329153547596 -0.4920684723609338
1.0116329153547596 1.0116329153547596 -0.7703887858517308

how can i make it plot a simple heatmap even if some tiles would be missing? From what i've seen online having integer pixel coordinates shouldn't be a must, but maybe the sparsity is an issue(?)


Solution

  • You could also use the plotting style with boxxyerror to plot your heatmap (check help boxxyerror). If you have a regular grid and you don't want to manually tune the box size to get a fully colored area you can let gnuplot extract the minimum step size in x and y automatically.

    Script:

    ### 2D heatmap with boxxyerrors and automatic boxsize
    reset session
    
    $Data <<EOD
    0.9882380255806047 0.9882380255806047 -0.7703887858517308
    0.9882380255806047 0.9929170035354357 -0.03247814980870606
    0.9882380255806047 0.9975959814902666 -0.6944306255482046
    0.9882380255806047 1.0022749594450977 -0.746165843927831
    0.9882380255806047 1.0069539373999286 -0.5151139695781666
    0.9882380255806047 1.0116329153547596 -0.1838806386646351
    0.9929170035354357 0.9929170035354357 -0.7703887858517308
    0.9929170035354357 0.9975959814902666 -0.9227715329230436
    0.9929170035354357 1.0022749594450977 -0.9171361902702745
    0.9929170035354357 1.0069539373999286 -0.7797704881116272
    0.9929170035354357 1.0116329153547596 -0.6650103546953546
    0.9975959814902666 0.9975959814902666 -0.7703887858517308
    0.9975959814902666 1.0022749594450977 -0.9065086173718683
    0.9975959814902666 1.0069539373999286 -0.3481667020388293
    0.9975959814902666 1.0116329153547596 0.10123715036482903
    1.0022749594450977 1.0022749594450977 -0.7703887858517308
    1.0022749594450977 1.0069539373999286 -0.28406345548617745
    1.0022749594450977 1.0116329153547596 0.1835875555217213
    1.0069539373999286 1.0069539373999286 -0.7703887858517308
    1.0069539373999286 1.0116329153547596 -0.4920684723609338
    1.0116329153547596 1.0116329153547596 -0.7703887858517308
    EOD
    
    # find the smallest dx,dy > 0
    stats $Data u ($0==0?(x0=$1,y0=$2):0, dx=abs(x0-$1), dx==0 ? NaN : dx) : \
                  (dy=abs(y0-$2), dy==0 ? NaN : dy) nooutput
    dx = STATS_min_x/2.
    dy = STATS_min_y/2.
    
    set palette rgb 33,13,10
    set size ratio -1
    set style fill solid 1.0
    set key noautotitle
    
    plot $Data u 1:2:(dx):(dy):3 w boxxy palette
    ### end of script
    

    Result:

    enter image description here

    Addition:

    Just for completeness, the automatic search for dx,dy>0 in the above script would fail with the data in the example below. The data below is (especially chosen) such that even if you (alternatively) compare the difference of two successive x (or y) values to find the minimum dx and dy it would fail. Hence you need a bit more effort.

    • plot the data into the temporary datablock $Temp by using the option smooth freqency (check help smooth frequency). With this you get unique values in ascending order. Do this for x-column and y-column.
    • since the sorted data for x and y in $Temp will be separated by two empty lines, you can address it via index (check help index).
    • use stats to calculate the difference between successive data points in $Temp and get the minimum in the variable STATS_min.

    Script:

    ### 2D heatmap with boxxyerrors and automatic boxsize
    reset session
    
    $Data <<EOD
      1   3   1.5
      1   5   1.9
      3   1   3.1
      5   4   5.7
      5   1   5.1
      3   4   3.7
      1   4   1.7
      4   4   4.7
      4   1   4.1
      4   3   4.5
      4   5   4.9
      1   1   1.1
      5   3   5.5
      5   5   5.9
      3   3   3.5
      3   5   3.9
    EOD
    
    # find the smallest dx,dy > 0
    set table $Temp
        plot $Data u 1:0 smooth freq
        plot $Data u 2:0 smooth freq
    unset table
    v1 = NaN
    stats $Temp u (v0=v1,v1=$1,dv=v1-v0) index 0 nooutput
    dx = STATS_min/2.
    v1 = NaN
    stats $Temp u (v0=v1,v1=$1,dv=v1-v0) index 1 nooutput
    dy = STATS_min/2.
    
    set palette rgb 33,13,10
    set size ratio -1
    set style fill solid 1.0 noborder
    set key noautotitle
    
    plot $Data u 1:2:(dx):(dy):3 w boxxy palette
    ### end of script
    

    Result:

    enter image description here