4

I have some problems drawing a radar chart.

I would like to draw the following chart.

enter image description here

I tried to paste pieces of code found here and there (I know that is not a good way) and I obtained the following result.

enter image description here

Any suggestion?

It's a WEEK that I am trying to do this. Thanks in advance for your help!!

Data used are:

colonna1 colonna2 
4 12 
3 2 
.02 .1 

And the code is the following:

\documentclass[a4paper,twoside,12pt]{book}

\usepackage[T1]{fontenc}
\usepackage[utf8x]{inputenc}
\usepackage[english]{babel}
\usepackage{pgfplotstable, pgfplots}

\begin{document}

\begin{tikzpicture}
\Kiviat{table.dat}
{C,N,P}
{red,orange}
{.5}
{.5}
\end{tikzpicture}

\end{document}

With these commands:

\makeatletter
\newcommand{\Kiviat}[5]{
% #1 - Table file
% #2 - List of the axis label. His lenght cannot be higher that the number of column of the table.
%      It can be lower
% #3 - Color list. His lenght cannot be higher that the number of column of the table.
%      It can be lower
% #4 - Pitch of th grid lines
% #5 - Axis line width 

% LOAD TABLE
% The table must be n x m where each n column is the m plot in function of the angle.
% The first row(labeled by pgfplots table like 0) must contain the name of every column
\pgfplotstableread{#1}\table

% COMPUTETATION OF TABLE DIMENSION
%->number of axis
\pgfplotstablegetrowsof{\table}
\pgfmathsetmacro{\axisNumber}{\pgfplotsretval-1}
%\show\axisNumber

%-> number of the column to compute
\pgfplotstablegetcolsof{\table}
\pgfmathsetmacro{\columnNumber}{\pgfplotsretval-1}
%\show\columnNumber

% LOAD AXIS LABEL
\def\namesAxis{#2}
\foreach \x[count=\kk] in \namesAxis{}

\pgfmathparse{\kk<=(\axisNumber+1)}
\ifnum\pgfmathresult=0
\errmessage{The number of labels is greater that number of column of the table loaded}
\fi

% LOAD COLOR LIST
\def\listaColori{#3}
\foreach \mese[count=\numeroColori] in \listaColori{}
%\show\numeroColori

\pgfmathparse{\numeroColori<=(\columnNumber+1)}
\ifnum\pgfmathresult=0
\errmessage{Il numero dei colori è maggiore delle colonne dei dati}
\fi

% COMPUTE THE MAXIMUM ELEMENT INTO THE TABLE TO COMPUTE THE RADIUS OF KIVIAT DIAGRAM
% -> starting value
\def\maxRadius{0}

\count1=0%\columnNumber
\count2=0%\axisNumber
\countdef\val=0
\def\maxRadius{0}

\loop
\ifnum\count1<\columnNumber
\advance\count1 by 1

{\loop
\ifnum\count2<\axisNumber
\advance\count2 by 1

\pgfplotstablegetelem{\count2}{[index]\count1}\of\table

\pgfmathparse{\maxRadius<\pgfplotsretval}

\ifnum\pgfmathresult=1
\pgfmathsetmacro{\maxRadius}{\pgfplotsretval}
\node (Max) at (0,\maxRadius){};
\fi
\repeat}

\count2=0
\repeat
% now the value of the maximum value into the table is stored in coordinate y of (Max) point in pt units.
% It must be converted in unit less number in centimenter and saved into \radius variable

\pgfextracty{\pgf@x}{(Max)}
%pgfmathsetmacro{\radius}{}
\pgfmathsetmacro{\radius}{ceil(abs(\pgf@x)*2.54/72)}

% COMPUTE THE GRID LINES NUMBER
\def\pitch{#4}
\pgfmathsetmacro{\numberTick}{\radius/\pitch}


% AXIS LINE WIDTH
\def\lwidth{#5}

% COMPUTE OF THE ANGLE BETWEEN THE AXIS
\pgfmathsetmacro{\ang}{360/(\axisNumber+1)}

% COMPUTE OF TICK RADIUS
\pgfmathsetmacro{\tickRadius}{1.5*\lwidth}

% GRID DRAWING
\begin{pgfscope}
\pgfsetlinewidth{.5pt}
\pgfsetstrokecolor{gray!50}
\foreach \altezza in {0,1,...,\numberTick}{
\pgfmathsetmacro{\dist}{\altezza*\pitch}
\foreach \axis in {0,1,...,\axisNumber}{
\ifnum\axis=0
\pgfpathmoveto{\pgfpointpolar{\ang*(\axis+1)}{\dist cm}}%
\else
\pgfpathlineto{\pgfpointpolar{\ang*(\axis+1)}{\dist cm}}
\fi}
\pgfpathclose
\pgfusepath{stroke}
}
\end{pgfscope}

% AXIS  and CIRCLE TICK DRAWING
\foreach \axis in {0,1,...,\axisNumber}{
\draw[->, line width=\lwidth pt] (0,0)--++(\ang*\axis:{\radius+1});
\foreach \tickPosition in {1,...,\numberTick}{
\fill (\ang*\axis:\pitch*\tickPosition)circle(\tickRadius pt);
}
}

% TICK DRAWING
\foreach \tick in {1,2,...,\radius}{
\node[anchor=south west] at (\tick,0){\tick};
}

% AXIS LABELING
\foreach \axis[count=\kk] in \namesAxis{
% \ang between 270 and 360
\pgfmathparse{(\ang*(\kk-1))<360&&(\ang*(\kk-1))>270}
\ifnum\pgfmathresult=1
\def\anchor{north west}
\fi

% \ang between 180 and 270
\pgfmathparse{(\ang*(\kk-1))<270&&(\ang*(\kk-1))>180}
\ifnum\pgfmathresult=1
\def\anchor{north east}
\fi

% \ang between 90 and 180
\pgfmathparse{(\ang*(\kk-1))<180&&(\ang*(\kk-1))>90}
\ifnum\pgfmathresult=1
\def\anchor{south east}
\fi

% \ang between  0 and 90
\pgfmathparse{(\ang*(\kk-1))<90&&(\ang*(\kk-1))>0}
\ifnum\pgfmathresult=1
\def\anchor{south west}
\fi

% \ang nei 4 punti cartinali
% east
\pgfmathparse{(\ang*(\kk-1))==0}
\ifnum\pgfmathresult=1
\def\anchor{west}
\fi
% nord
\pgfmathparse{(\ang*(\kk-1))==90}
\ifnum\pgfmathresult=1
\def\anchor{south}
\fi
% west
\pgfmathparse{(\ang*(\kk-1))==180}
\ifnum\pgfmathresult=1
\def\anchor{east}
\fi
% south
\pgfmathparse{(\ang*(\kk-1))==270}
\ifnum\pgfmathresult=1
\def\anchor{north}
\fi

\node[anchor=\anchor] at ({\ang*(\kk-1)}:{\radius+1}){\axis};
}

% FILE PLOTTING
\pgfplotstableforeachcolumn\table\as\nomeColonne{%
\begin{pgfscope}

% color definition
\pgfmathsetmacro{\cucu}{\pgfplotstablecol+1}
\foreach \var[count=\kk] in \listaColori{
\ifnum\kk=\cucu
\pgfsetstrokecolor{\var}
\fill[shift={(\radius cm+2 cm,-\pgfplotstablecol cm+\radius cm)},\var] (0,0)rectangle(.5,.1);
\node[shift={(\radius cm+2 cm,-\pgfplotstablecol cm+\radius cm)}, anchor=west] at (0,-.25){\nomeColonne};
\breakforeach
\fi
}


\foreach \axis in {0,1,...,\axisNumber}{
\pgfplotstablegetelem{\axis}{[index]\pgfplotstablecol}\of\table
\pgfmathsetmacro{\data}{\pgfplotsretval}
\ifnum\axis=0
\pgfpathmoveto{\pgfpointpolar{\ang*\axis}{\data cm}}%
\else
\pgfpathlineto{\pgfpointpolar{\ang*\axis}{\data  cm}}
\fi
}
\pgfsetlinewidth{2pt}
\pgfclosepath
\pgfusepath{stroke}
\end{pgfscope}}
}
\makeatother

SOLVED:

\documentclass[a4paper,twoside,12pt]{book}

\usepackage[T1]{fontenc}
\usepackage[utf8x]{inputenc}
\usepackage[english]{babel}
\usepackage{pgfplotstable, pgfplots, filecontents}

\makeatletter
\newcommand{\Kiviat}[6]{
% #1 - Table file
% #2 - List of the axis label. His lenght cannot be higher that the number of column of the table.
%      It can be lower
% #3 - Color list. His lenght cannot be higher that the number of column of the table.
%      It can be lower
% #4 - Pitch of th grid lines
% #5 - Axis line width 

% LOAD TABLE
% The table must be n x m where each n column is the m plot in function of the angle.
% The first row(labeled by pgfplots table like 0) must contain the name of every column
\pgfplotstableread{#1}\table

% COMPUTETATION OF TABLE DIMENSION
%->number of axis
\pgfplotstablegetrowsof{\table}
\pgfmathsetmacro{\axisNumber}{\pgfplotsretval-1}
%\show\axisNumber

%-> number of the column to compute
\pgfplotstablegetcolsof{\table}
\pgfmathsetmacro{\columnNumber}{\pgfplotsretval-1}
%\show\columnNumber

% LOAD AXIS LABEL
\def\namesAxis{#2}
\foreach \x[count=\kk] in \namesAxis{}

\pgfmathparse{\kk<=(\axisNumber+1)}
\ifnum\pgfmathresult=0
\errmessage{The number of labels is greater that number of column of the table loaded}
\fi

% LOAD COLOR LIST
\def\listaColori{#3}
\foreach \mese[count=\numeroColori] in \listaColori{}
%\show\numeroColori

\pgfmathparse{\numeroColori<=(\columnNumber+1)}
\ifnum\pgfmathresult=0
\errmessage{Il numero dei colori è maggiore delle colonne dei dati}
\fi

% COMPUTE THE MAXIMUM ELEMENT INTO THE TABLE TO COMPUTE THE RADIUS OF KIVIAT DIAGRAM
% -> starting value
\def\maxRadius{0}

\count1=0%\columnNumber
\count2=0%\axisNumber
\countdef\val=0
\def\maxRadius{0}

\loop
\ifnum\count1<\columnNumber
\advance\count1 by 1

{\loop
\ifnum\count2<\axisNumber
\advance\count2 by 1

\pgfplotstablegetelem{\count2}{[index]\count1}\of\table

\pgfmathparse{\maxRadius<\pgfplotsretval}

\ifnum\pgfmathresult=1
\pgfmathsetmacro{\maxRadius}{\pgfplotsretval}
\node (Max) at (0,\maxRadius){};
\fi
\repeat}

\count2=0
\repeat
% now the value of the maximum value into the table is stored in coordinate y of (Max) point in pt units.
% It must be converted in unit less number in centimenter and saved into \radius variable

\pgfextracty{\pgf@x}{(Max)}
%pgfmathsetmacro{\radius}{}
\pgfmathsetmacro{\radius}{ceil(abs(\pgf@x)*2.54/72)}

% COMPUTE THE GRID LINES NUMBER
\def\pitch{#4}
\pgfmathsetmacro{\numberTick}{\radius/\pitch}


% AXIS LINE WIDTH
\def\lwidth{#5}

% COMPUTE OF THE ANGLE BETWEEN THE AXIS
\pgfmathsetmacro{\ang}{360/(\axisNumber+1)}

% COMPUTE OF TICK RADIUS
\pgfmathsetmacro{\tickRadius}{1.5*\lwidth}

% GRID DRAWING
\begin{pgfscope}
\pgfsetlinewidth{.5pt}
\pgfsetstrokecolor{gray!50}
\foreach \altezza in {0,1,...,\numberTick}{
\pgfmathsetmacro{\dist}{\altezza*\pitch}
\foreach \axis in {0,1,...,\axisNumber}{
\ifnum\axis=0
\pgfpathmoveto{\pgfpointpolar{\ang*(\axis+1)}{\dist cm}}%
\else
\pgfpathlineto{\pgfpointpolar{\ang*(\axis+1)}{\dist cm}}
\fi}
\pgfpathclose
\pgfusepath{stroke}
}
\end{pgfscope}

% AXIS  and CIRCLE TICK DRAWING
\foreach \axis in {0,1,...,\axisNumber}{
\draw[->, line width=\lwidth pt] (0,0)--++(\ang*\axis:{\radius+1});
\foreach \tickPosition in {1,...,\numberTick}{
\fill (\ang*\axis:\pitch*\tickPosition)circle(\tickRadius pt);
}
}

% TICK DRAWING
\pgfplotstableread{#6}\qwerty
\foreach \axis[count=\kk] in \namesAxis{
\foreach \tick in {1,2,3}{
\pgfplotstablegetelem{\kk}{\tick}\of\qwerty
\pgfmathsetmacro{\etichetta}{\pgfplotsretval}
\pgfmathsetmacro{\x}{\tick*cos((\ang*(\kk-1))}
\pgfmathsetmacro{\y}{\tick*sin((\ang*(\kk-1))}
\pgfmathparse{sin((\ang*(\kk-1))}
\node[anchor=south west] at (\x,\y){\etichetta};
}
}

% AXIS LABELING
\foreach \axis[count=\kk] in \namesAxis{
% \ang between 270 and 360
\pgfmathparse{(\ang*(\kk-1))<360&&(\ang*(\kk-1))>270}
\ifnum\pgfmathresult=1
\def\anchor{north west}
\fi

% \ang between 180 and 270
\pgfmathparse{(\ang*(\kk-1))<270&&(\ang*(\kk-1))>180}
\ifnum\pgfmathresult=1
\def\anchor{north east}
\fi

% \ang between 90 and 180
\pgfmathparse{(\ang*(\kk-1))<180&&(\ang*(\kk-1))>90}
\ifnum\pgfmathresult=1
\def\anchor{south east}
\fi

% \ang between  0 and 90
\pgfmathparse{(\ang*(\kk-1))<90&&(\ang*(\kk-1))>0}
\ifnum\pgfmathresult=1
\def\anchor{south west}
\fi

% \ang nei 4 punti cartinali
% east
\pgfmathparse{(\ang*(\kk-1))==0}
\ifnum\pgfmathresult=1
\def\anchor{west}
\fi
% nord
\pgfmathparse{(\ang*(\kk-1))==90}
\ifnum\pgfmathresult=1
\def\anchor{south}
\fi
% west
\pgfmathparse{(\ang*(\kk-1))==180}
\ifnum\pgfmathresult=1
\def\anchor{east}
\fi
% south
\pgfmathparse{(\ang*(\kk-1))==270}
\ifnum\pgfmathresult=1
\def\anchor{north}
\fi

\node[anchor=\anchor] at ({\ang*(\kk-1)}:{\radius+1}){\axis};
}

% FILE PLOTTING
\pgfplotstableforeachcolumn\table\as\nomeColonne{%
\begin{pgfscope}

% color definition
\pgfmathsetmacro{\cucu}{\pgfplotstablecol+1}
\foreach \var[count=\kk] in \listaColori{
\ifnum\kk=\cucu
\pgfsetstrokecolor{\var}
\fill[shift={(\radius cm+2 cm,-\pgfplotstablecol cm+\radius cm)},\var] (0,0)rectangle(.5,.1);
\node[shift={(\radius cm+2 cm,-\pgfplotstablecol cm+\radius cm)}, anchor=west] at (0,-.25){\nomeColonne};
\breakforeach
\fi
}

\foreach \axis in {0,1,...,\axisNumber}{
\pgfplotstablegetelem{\axis}{[index]\pgfplotstablecol}\of\table
\pgfmathsetmacro{\data}{\pgfplotsretval}
\ifnum\axis=0
\pgfpathmoveto{\pgfpointpolar{\ang*\axis}{\data cm}}%
\else
\pgfpathlineto{\pgfpointpolar{\ang*\axis}{\data  cm}}
\fi
}
\pgfsetlinewidth{2pt}
\pgfclosepath
\pgfusepath{stroke}
\end{pgfscope}}
}
\makeatother

\begin{document}

\begin{filecontents*}{axis.dat}
3 6 9 1
1 2 3 23
.2 .4 .6 21
1 1 1 2
\end{filecontents*}

\begin{filecontents*}{coord.dat}
colonna1 colonna2 
4 12 
3 2 
.02 .1 
\end{filecontents*}

\begin{tikzpicture}
\Kiviat{coord.dat}{C,N,P}{red,orange}{1}{.5}{axis.dat}
\end{tikzpicture}

\end{document}
  • 2
    Are you familiar with Tkz-kiviat from our Alain Matthes ? Documentation is in French but the examples are self-explanatory. – percusse Jul 12 '15 at 7:05
  • yes I ve read that documentation but it doesn't explain how to make axis with different scale – Stefano Jul 12 '15 at 10:25
2

You can draw this shape with tikz-3dplot. This is the final result

enter image description here

I've added scale variables in x and y data so that you can change them.

% scale your data 
\def \yscal {0.5}   
\def \xscal {2}

Change them if you want to zoom in or out. This is the code for your case.

\documentclass{article}
\usepackage[table,dvipsnames]{xcolor}
\usepackage{tikz}  
\usepackage{tikz-3dplot} 

% change the camera position
\tdplotsetmaincoords{40}{125}

\begin{document}

\begin{tikzpicture}[scale=.5,
                    x={(\raarot cm,\rbarot cm)},%
                    y={(\rabrot cm, \rbbrot cm)},%
                    z={(\racrot cm, \rbcrot cm)}]

% scale your data 
\def \yscal {0.5}   
\def \xscal {2}

\draw [->] (0,0,0) -- (5,0,0) node[anchor=west]{$x$};
\draw [->] (0,0,0) -- (0,\yscal*15,0) node[anchor=north west]{$y$};
\draw [->] (0,0,0) -- (0,0,5) node[anchor=west]{$z$};   




\path [fill=red!50, opacity=.4] 
(\xscal*1,0,0) -- (0,\yscal*12,0) -- (0,0,3) -- cycle;  

\path [fill=green!50, opacity=.4] 
(\xscal*.2,0,0) -- (0,\yscal*4,0) -- (0,0,3) -- cycle; 

\path [fill=blue!50, opacity=.4] 
(\xscal*1,0,0) -- (0,\yscal*12,0) -- (0,0,2) -- cycle;  


% draw ticks in x-axis
\foreach \x in {0, 0.2, 0.4, 0.6,0.8, 1}
\draw [thin, gray] (\xscal*\x, -.1, 0) -- (\xscal*\x, .1, 0) 
node[black,scale=.2,yshift=5mm,xshift=-5mm, rotate=-90] {\x};

% draw ticks in y-axis
\foreach \y in {0, 1, ..., 12}
\draw [thin, gray] (-.1, \yscal*\y, 0) -- (.1, \yscal*\y, 0) 
node[black,scale=.2,yshift=3mm,xshift=3mm] {\y};

% draw ticks in z-axis  
\foreach \z in {0,1, 2, 3}
\draw [thin, gray] (0, -.1, \z) -- (0, .1,\z) 
node[black,scale=.2,yshift=0mm,xshift=-0mm] {\z};   


\draw (0,0,3) node[scale=.7, right] {$v$};
\draw (0,\yscal*12,0) node[scale=.7, right] {$c$};
\draw (\xscal*1,0,0) node[scale=.7, below] {$p$};   
\end{tikzpicture}


\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.