7 votes

Comment créer un graphique en araignée dans Gnuplot ?

Je voudrais produire un graphique araignée (ou radar/étoile) à l'aide de Gnuplot où les différents axes ont des échelles indépendantes. Je suis capable de produire un tel tracé en utilisant OriginPro (commercial), mais avec Gnuplot je ne suis capable que de définir un tracé radar avec une échelle uniforme.

L'ensemble de données (fichier csv) ressemble à ce qui suit (la première ligne est constituée des étiquettes des colonnes) :

# FEATURE, Product_A, Product_B, Product_C, Product_D
attribute_1, 2, 10, 7, 3.5
attribute_2, 1, 0.5, 3,4
attribute_3, 37, 58, 49, 72
attribute_4, 1985, 1992, 2006, 2010
attribute_5, 0.1, 0.5, 0.3, 0.8

et l'intrigue que je recherche est celle-ci : https://www.dropbox.com/s/uvqubzqvm6puhb8/spider.pdf - Comme vous pouvez le constater, chaque axe représente un attribut différent et possède sa propre échelle.

Je suppose que le code de départ de Gnuplot est :

set polar
set grid polar
set angles degrees
set size square
set style data filledcurves

Mais je ne sais pas comment procéder. Avez-vous des suggestions ?

3voto

george Points 2473

Voici une tentative de piratage

set nokey
set polar
set grid polar
set angles degrees
set size square
set style data lines
a1=0
a2=30
a3=100
a4=200
a5=300
set arrow nohead from 0,0 to first 10*cos(a1) , 10*sin(a1)
set arrow nohead from 0,0 to first 10*cos(a2) , 10*sin(a2)
set arrow nohead from 0,0 to first 10*cos(a3) , 10*sin(a3)
set arrow nohead from 0,0 to first 10*cos(a4) , 10*sin(a4)
set arrow nohead from 0,0 to first 10*cos(a5) , 10*sin(a5)
set xrange [-10:10]
set yrange [-10:10]
plot '-' using ($1==1?a1:($1==2?a2:($1==3?a3:($1==4?a4:($1==5?a5:$1))))):2 lt 2
1 4
2 8
3 6
4 9
5 5
1 4

3voto

theozh Points 1727

Voici une suggestion de "spider-plot" tirée de ma collection. Puisqu'il utilise des données provenant d'un bloc de données plutôt que d'un fichier (parce qu'il est plus facile d'adresser certaines lignes, par exemple par le biais de $Data[1] ), par conséquent, il nécessite gnuplot >=5.2.0 . Les données réelles sont dans $Data et certains paramètres pour les gammes et les ajustements de décalage personnalisés sont en $Settings . Le nombre d'axes est automatiquement ajusté si vous ajoutez des lignes supplémentaires dans la base de données. $Data y $Settings . Les données doivent être séparées par des espaces, car la fonction gnuplot word(string,number) est utilisé pour extraire certaines valeurs.

J'espère que cela s'explique plus ou moins bien. Les commentaires, les rapports de bugs ou d'améliorations sont les bienvenus.

Código:

### spider plot/chart with gnuplot 
# also known as: radar chart, web chart, star chart, cobweb chart, 
#                radar plot,  web plot,  star plot,  cobweb plot,  etc. ...
reset session
set size square
unset tics
set angles degree
set key top left

# Data
$Data <<EOD
SpiderData     "Product A"  "Product B"  "Product C"  "Product D"
Colors                red        green         blue       violet
"attribute 1"           2           10            7          3.5
"attribute 2"           1          0.5            3            4
"attribute 3"          37           58           49           72
"attribute 4"        1985         1992         2006         2010
"attribute 5"         0.1          0.5          0.3          0.8
EOD
HeaderLines = 2

# Settings for scale and offset adjustments
# axis min max tics axisLabelXoff axisLabelYoff ticLabelXoff ticLabelYoff
$Settings <<EOD
1     0    12  6  0.00 -0.02 -0.05  0.00
2     0     6  6  0.00  0.05  0.00  0.05
3    30    90  6  0.00  0.00  0.05  0.03
4  1980  2016  6  0.00  0.00  0.09 -0.02
5     0   1.2  6  0.00  0.05  0.00 -0.05
EOD

# General settings
DataColCount = words($Data[1])-1
AxesCount = |$Data|-HeaderLines
AngleOffset = 90
Max = 1
d=0.1*Max
Direction = -1   # counterclockwise=1, clockwise = -1

# Tic settings
TicCount = 6
TicValue(axis,i) = real(i)*(word($Settings[axis],3)-word($Settings[axis],2)) \
          / word($Settings[axis],4)+word($Settings[axis],2)
TicLabelPosX(axis,i) = PosX(axis,i/TicCount) + word($Settings[axis],7)
TicLabelPosY(axis,i) = PosY(axis,i/TicCount) + word($Settings[axis],8)
TicLen = 0.03
TicdX(axis,i) = 0.5*TicLen*cos(alpha(axis)-90)
TicdY(axis,i) = 0.5*TicLen*sin(alpha(axis)-90)

# Functions
alpha(axis) = (axis-1)*Direction*360.0/AxesCount+AngleOffset
PosX(axis,R) = R*cos(alpha(axis))
PosY(axis,R) = R*sin(alpha(axis))
Scale(axis,value) = real(value-word($Settings[axis],2))/(word($Settings[axis],3)-word($Settings[axis],2))

# Spider settings
set style arrow 1 dt 1 lw 1.0 lc -1 head     # style for axes
set style arrow 2 dt 2 lw 0.5 lc -1 nohead   # style for weblines
set style arrow 3 dt 1 lw 1 lc -1 nohead     # style for axis tics
set samples AxesCount
set isosamples TicCount
set urange[1:AxesCount]
set vrange[1:TicCount]
do for [i=1:DataColCount] {                  # set linetypes/colors
    set linetype i lc rgb word($Data[2],i+1)
}
set style fill transparent solid 0.2

set xrange[-Max-4*d:Max+4*d]
set yrange[-Max-4*d:Max+4*d]
plot \
    '+' u (0):(0):(PosX($0,Max+d)):(PosY($0,Max+d)) w vec as 1 not, \
    $Data u (PosX($0+1,Max+2*d)+word($Settings[$0+1],5)): \
        (PosY($0+1,Max+2*d)+word($Settings[$0+1],6)):1 every ::HeaderLines w labels center enhanced not, \
    '++' u (PosX($1,$2/TicCount)):(PosY($1,$2/TicCount)): \
        (PosX($1+1,$2/TicCount)-PosX($1,$2/TicCount)):  \
        (PosY($1+1,$2/TicCount)-PosY($1,$2/TicCount)) w vec as 2 not, \
    '++' u (PosX($1,$2/TicCount)-TicdX($1,$2/TicCount)): \
        (PosY($1,$2/TicCount)-TicdY($1,$2/TicCount)): \
        (2*TicdX($1,$2/TicCount)):(2*TicdY($1,$2/TicCount)) \
        w vec as 3 not, \
    for [i=1:DataColCount] $Data u (PosX($0+1,Scale($0+1,column(i+1)))): \
        (PosY($0+1,Scale($0+1,column(i+1)))) every ::HeaderLines w filledcurves lt i title word($Data[1],i+1), \
    '++' u (TicLabelPosX($1,$2)):(TicLabelPosY($1,$2)): \
        (sprintf("%g",TicValue($1,$2))) w labels font ",8" not
### end of code

Résultat :

enter image description here

1voto

CarloAlberto Points 99

La réponse de @george m'a aidé à comprendre comment réorganiser l'ensemble de données, afin d'y prélever les données d'attribut correspondantes. Comme je cherchais également des échelles différentes pour les différents axes de l'araignée, en plus de la suggestion de @george, j'ai pensé qu'une normalisation spécifique de l'axe à l'échelle commune [0:1] aurait résolu le problème. La principale modification est alors liée à la using du champ de la plot commandement.

Le code est assez long, je suis sûr qu'il pourrait être optimisé. Il pourrait également être fusionné dans un script ou un simple code C, afin de laisser l'utilisateur décider du nombre d'axes (nombre d'attributs), et des différentes plages (min, max) pour chaque axe spécifique.

L'exemple suivant concerne 5 attributs comparant 2 produits. On voit ici le image du résultat du tracé :

set nokey
set polar
set angles degrees
npoints = 5
a1 = 360/npoints*1
a2= 360/npoints*2
a3= 360/npoints*3
a4= 360/npoints*4
a5= 360/npoints*5
set grid polar 360.
set size square
set style data lines
unset border
set arrow nohead from 0,0 to first 1*cos(a1) , 1*sin(a1)
set arrow nohead from 0,0 to first 1*cos(a2) , 1*sin(a2)
set arrow nohead from 0,0 to first 1*cos(a3) , 1*sin(a3)
set arrow nohead from 0,0 to first 1*cos(a4) , 1*sin(a4)
set arrow nohead from 0,0 to first 1*cos(a5) , 1*sin(a5)
a1_max = 10
a2_max = 5
a3_max = 100
a4_max = 2020
a5_max = 1
a1_min = 0
a2_min = 0
a3_min = 50
a4_min = 1980
a5_min = 0
set label "(0:10)" at cos(a1),sin(a1) center offset char 1,1
set label "(0:5)" at cos(a2),sin(a2) center offset char -1,1
set label "(50:100)" at cos(a3),sin(a3) center offset char -1,-1
set label "(1980:2020)" at cos(a4),sin(a4) center offset char 0,-1
set label "(0:1)" at cos(a5),sin(a5) center offset char 3,0
set xrange [-1:1]
set yrange [-1:1]
unset xtics
unset ytics
set rrange [0:1]
set rtics (""0,""0.25,""0.5,""0.75,""1)

plot '-' using ($1==1?a1:($1==2?a2:($1==3?a3:($1==4?a4:($1==5?a5:$1))))):($1==1?(($2-a1_min)/(a1_max-a1_min)):($1==2?(($2-a2_min)/(a2_max-a2_min)):($1==3?(($2-a3_min)/(a3_max-a3_min)):($1==4?(($2-a4_min)/(a4_max-a4_min)):($1==5?(($2-a5_min)/(a5_max-a5_min)):$1))))) w l
1 8
2 3
3 67
4 2000
5 0.2
1 8

plot '-' using ($1==1?a1:($1==2?a2:($1==3?a3:($1==4?a4:($1==5?a5:$1))))):($1==1?(($2-a1_min)/(a1_max-a1_min)):($1==2?(($2-a2_min)/(a2_max-a2_min)):($1==3?(($2-a3_min)/(a3_max-a3_min)):($1==4?(($2-a4_min)/(a4_max-a4_min)):($1==5?(($2-a5_min)/(a5_max-a5_min)):$1))))) w l
1 6
2 1.5
3 85
4 2010
5 0.5
1 6

0voto

orey Points 11

Le repo suivant montre un graphique araignée avec des échelles homogènes. https://github.com/orey/gnuplot-radarchart

Pour votre cas particulier, je le ferais : -Créer des fonctions qui normalisent toutes les données pour qu'elles s'adaptent à l'échelle du diagramme, -Cacher l'échelle standard, -Utiliser des flèches pour l'axe, -Ajouter des points avec des étiquettes pour vos échelles particulières et les placer avec vos fonctions de données.

Je pense que l'inspiration peut être trouvée dans le repo.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X