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

Viewed 52

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(?)

2 Answers

You may need to clarify exactly what you want, and what you know in advance about your data properties. For now I suggest you might try this and see if it comes close to what you intended:

set size ratio -1    # make sure that a square is really a square
unset key
set palette cubehelix negative
set pointsize 10     # adjust if needed to make the pixels touch
plot 'foo' using 1:2:3 with points pointtype 5 fillcolor palette

enter image description here

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

Related