2

Let's say my data is in the form:

#atom a b c
43 1.2 1.3 1.4
44 1.2 1.4 1.8
45 1.3 1.8 1.9
46 2.0 2.3 2.4
47 1.5 1.6 1.8

And I want a plot like this one http://www.r-graph-gallery.com/143-spider-chart-with-saveral-individuals/ (the one in the middle).

how can I do that?

ps. The title in here (How to Create a Spider Plot in Gnuplot?) is misleading...

murpholinox
  • 639
  • 1
  • 4
  • 14

1 Answers1

2

As far as I know, there is no built-in functionality which would directly give you the linked output. Nevertheless, one could improvise with the tools that Gnuplot does provide. The strategy would be to:

  1. analyze the file and determine the number of vertices
  2. generate the "polygonial" grid in parametric mode
  3. plot the data using the filledcurves plotting style (with transparency)

For example (the data is represented as a datablock instead of directly passing a file):

reset session
set terminal pngcairo enhanced font "Times,16"
set output 'plot.png'

$DATA << EOD
#atom a b c
43 1.2 1.3 1.4
44 1.2 1.4 1.8
45 1.3 1.8 1.9
46 2.0 2.3 2.4
47 1.5 1.6 1.8
EOD

stats $DATA nooutput

N = STATS_columns
M = STATS_records

set angles degrees
set size ratio -1
set style fill transparent solid 0.25

unset key
unset border
unset xtics
unset ytics

colors = "dark-red royalblue forest-green"

set style line 42 lt 1 lc rgb '#333333' dt 3 lw 0.8

deltaR = 0.5
maxR = 3 + deltaR/4
numOfStepsInR = floor((1.*maxR) / deltaR)

#helper functions
alpha(i) = 90. - i*360./M
posX(i, r) = cos(alpha(i))*r
posY(i, r) = sin(alpha(i))*r
lcolor(i) = word(colors, i%words(colors) + 1)

do for [i=0:M-1] {
  stats $DATA every ::i::i using (labelValue=$1) nooutput
  set label sprintf("%d", labelValue) at posX(i,maxR),posY(i,maxR) center offset char posX(i,1),char posY(i,1)
}

do for [j=1:numOfStepsInR] {
  set label sprintf("%.1f", j*deltaR) at 0,j*deltaR left offset char 0.5,0 tc rgb '#333333'
}

set parametric
set tr [0:1]

set xr [-1.1*maxR:1.1*maxR]
set yr [-1.1*maxR:1.1*maxR]

plot \
  for [i=0:M-1] \
    (cos(alpha(i))*(deltaR*(1-t)+t*maxR)),(sin(alpha(i))*(deltaR*(1-t)+t*maxR)) w l ls 42, \
  for [i=0:M-1] for [j=1:numOfStepsInR] \
    (j*deltaR*cos(alpha(i))*t + (1-t)*j*deltaR*cos(alpha(i+1))),(j*deltaR*sin(alpha(i))*t + (1-t)*j*deltaR*sin(alpha(i+1))) w l ls 42, \
  for [i=2:N] $DATA u (posX($0, column(i))):(posY($0, column(i))) w filledcurves closed fc rgb lcolor(i-2) fs border lc rgb lcolor(i-2) lw 2, \
  for [i=2:N] $DATA u (posX($0, column(i))):(posY($0, column(i))) w p ps 1.2 pt 7 lc rgb lcolor(i-2)

This produces: enter image description here

ewcz
  • 12,819
  • 1
  • 25
  • 47
  • the `array` line says it is an invalid command. Got gnuplot Version 5.0 patchlevel 6 – murpholinox Apr 16 '18 at 14:31
  • @murpholinox array support was added in 5.1, I have modified the answer so that it uses the `word` function workaround... – ewcz Apr 16 '18 at 15:24
  • Thanks a lot. would you care to explain it a little bit. :P – murpholinox Apr 16 '18 at 16:50
  • Thanks a lot for your answer. In fact, in my case the first column represented a string value (basically the name of the "vertexes" of the spider plot). Therefore, the trick of using the setlabel with sprintf did not work, as it required a stat command that failed. I solved by removing the setlabel loop and adding this plot line before all other plots ```plot datafile u (posX($0,maxR*1.1)):(posY($0,maxR*1.1)):1 w labels,\ ...``` – theleos Sep 12 '19 at 08:57