Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

From this post, I started to play with TikZ/PGF to draw a Kiviat Diagram froma a file .dat

Suppose to have two file table1.dat and table2.dat live these

%table1
column1 column2 
8.109115e-001 3.446073e+000 
3.971423e+000 3.740758e+000 
1.556075e+000 2.252708e+000 
2.642666e+000 4.191069e-001 
8.282436e-001 1.144885e+000 
3.009910e+000 4.566687e+000 
1.314856e+000 7.618901e-001 
3.270395e+000 4.129085e+000 

%table2
colonna1 colonna2 colonna3 colonna4 
4.073618e+000 4.785835e+000 3.393676e+000 3.474143e+000 
4.528960e+000 2.426878e+000 3.788701e+000 1.585497e+000 
6.349341e-001 4.001402e+000 3.715662e+000 4.751110e+000 
4.566879e+000 7.094317e-001 1.961135e+000 1.722304e-001 
3.161796e+000 2.108806e+000 3.277389e+000 2.193722e+000 
4.877020e-001 4.578678e+000 8.559334e-001 1.907792e+000 
1.392491e+000 3.961037e+000 3.530230e+000 3.827584e+000 
2.734408e+000 4.797462e+000 1.591642e-001 3.976000e+000 
4.787534e+000 3.278703e+000 1.384615e+000 9.343630e-001 
4.824443e+000 1.785584e-001 2.308570e-001 2.448822e+000 
7.880654e-001 4.245647e+000 4.856589e-001 2.227931e+000 
4.852964e+000 4.669966e+000 4.117289e+000 3.231565e+000

Here it is the explained code:

\documentclass{report}

\usepackage{tikz}
\usetikzlibrary{calc}

\usepackage{pgfplotstable}

\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength{\PreviewBorder}{5mm}
\pagestyle{empty}

\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,-.5);
\node[shift={(\radius cm+2 cm,-\pgfplotstablecol cm+\radius cm)}, anchor=west] at (.5,-.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{tikzpicture}%[scale=.65]
\Kiviat{table1.dat}
{row1,row2,ro3,row4,row5,ro6,row7,row8}
{red,orange}
{.5}
{1}
\end{tikzpicture}

\begin{tikzpicture}%[scale=.65]
\Kiviat{table2.dat}
{row1,row2,row3,row4,row5,row6,row7,row8,ro9,row10,row11,row12}
{red,orange,green!50!black,yellow!70!black}
{.5}
{1}
\end{tikzpicture}

\end{document}

These are the resultsTable1 enter image description here

For sure is not the best and more efficient code possible to write but it is a beginning.

Indeed, there is a big problem. If i scale the tikzpicture, not every component is scaled in the right way.

I'd like to introduce some pgfkeys to play with much more input. Can somebody help me?

Many thanks in advance

share|improve this question
2  
It is a little difficult to find out what your problem actually is. Please make sure it is more highlighted. You really should start with "I need help scaling the following TikZ picture ..." and have something like this also as title. –  Martin Scharrer Feb 4 '11 at 13:27
add comment

3 Answers 3

up vote 4 down vote accepted

I created a package to create tkz-kiviat diagram from a file.date . I add another example in this post how-to-draw-kiviat-diagrams

The example number 5 kiviat example used an external file. My package is based on TikZ and pgfplotstable.

:enter image description here

You can see that I use a lot of options ans styles from TikZ

\begin{tikzpicture}
\tkzKiviatDiagramFromFile[
        scale=.5,
        label distance=.5cm,
        gap     = 1,label space=3,  
        lattice = 10]{tableae.dat}
\tkzKiviatLineFromFile[thick,
                       color      = blue,
                       mark       = ball,
                       ball color = blue,
                       mark size  = 4pt,
                       fill       = blue!20]{tableae.dat}{2}
\tkzKiviatLineFromFile[thick,
                       color      = red,
                       mark       = ball,
                       ball color = red,
                       mark size  = 4pt,
                       fill       = red!20]{tableae.dat}{1} 
\end{tikzpicture} 
share|improve this answer
    
(+1) Really nice-looking plot! –  chl Feb 7 '11 at 22:37
add comment

I've taken a different approach: I draw the plots using pgfplots, which makes it possible to use stuff like the legend functions and plot styles.

I have also assumed that the row and column titles are in the datafile. I'm not sure if that's what is going to be the case for you, but I thought that this would make it easier to plot different datasets. It should be easy enough to change to an argument similar to the one you used, though.

The plots are resizable through a scale factor that influences a base length in the plot. This keeps all the font sizes and line widths unchanged. If you want to actually scale everything down, you should go with what Martin suggested.

Maybe this approach is not what you need, but I think at least the algorithm for searching for the maximum value in a table using pgfplotstable should be useful.

\documentclass{minimal}

\usepackage{pgfplots}
\usepackage{listings}


\usepackage{pgfplotstable}

\begin{document}

\newcommand\kiviat[1]{
\def\filename{#1}

\pgfplotstablevertcat{\dataA}{\filename} % Load table
\pgfplotstablegetrowsof{\dataA} % Determine no. of rows
\pgfmathsetmacro{\rows}{\pgfplotsretval}
\pgfplotstablegetcolsof{\dataA} % Determine no. of cols
\pgfmathsetmacro{\cols}{\pgfplotsretval-1} % Correct offset
\pgfplotstablevertcat{\dataA}{\dataA} % Double the table to close gap after last point
% Read table again with "header=false" which gives us access to the header names
\pgfplotstableread[header=false]{\filename}{\headertable}

% Not implemented: "\startingcol" could be used to switch between
%  row names in file and row names as argument
\def\startingcol{1}

% Find largest element
\pgfmathsetmacro\maxval{0}
\foreach \i in {\startingcol,...,\cols} {%
  \pgfplotstablesort[sort key={[index] \i},sort cmp={float >}]\sorted{\dataA}
  \pgfplotstablegetelem{0}{[index] \i}\of{\sorted}
  \pgfmathsetmacro\newval{ceil(max(\pgfplotsretval,\maxval))}
  \global\let\maxval=\newval
}

\pgfplotsset{every axis }

\newdimen\radius
\pgfmathsetlength\radius{4cm*\scalefactor}

\tikzstyle{grid}=[gray]

% Draw the grid
\foreach \i in {1,...,\rows} {
  \draw [grid,thick,->] (0,0) -- (\i/\rows*360:\radius+1em); % Spokes
  \pgfplotstablegetelem{\i}{[index] 0}\of{\dataA}
  % Spoke labels: some trigonometry to determine offset, needs tweaking
  \pgfmathsetmacro\dist{abs(cos(\i/\rows*360)*3} 
  \node at (\i/\rows*360:\radius+\dist ex+1.5em) [anchor=center] {\pgfplotsretval};
  % Points and grid lines
  \foreach \j in {1,...,\maxval} {
    \draw [fill,grid,black] (\i/\rows*360:\j*\radius/\maxval) circle (1pt); 
    \pgfmathsetmacro\nexti{\i+1}
    \draw [grid] (\i/\rows*360:\j*\radius/\maxval) -- (\nexti/\rows*360:\j*\radius/\maxval);
  }
}

% Tick labels
\foreach \j in {0,...,\maxval} {
  \node [anchor=south west,inner xsep=0pt,inner ysep=2pt] at (0:\j*\radius/\maxval) {\j};
}

% The actual plot area
\begin{axis}[anchor=center,
scale only axis, width=2\radius, height=2\radius, hide axis,
xmin=-\maxval,xmax=\maxval,ymin=-\maxval,ymax=\maxval,
legend style={ at={(1.03,1.08)}, anchor=north west}
]
\foreach \n in {\startingcol,...,\cols} {
% pgfplots doesn't know polar coordinate systems, that's why we'll use cos and sin
\addplot +[no markers,thick] table [x expr=cos(\pgfplotstablerow/\rows*360)*\thisrowno{\n},y expr=sin(\pgfplotstablerow/\rows*360)*\thisrowno{\n}] {\dataA};
\pgfplotstablegetelem{0}{\n}\of{\headertable}
\addlegendentryexpanded{\pgfplotsretval}
}
\end{axis}
}


\tikzstyle{every plot}+=[line width=2pt] % Can be used to influence plot style
\def\scalefactor{.65} % Scale factor multiplies the base length, everything else is relative to that
\begin{tikzpicture}
 \kiviat{table1.dat} 
\end{tikzpicture}

\tikzstyle{every plot}+=[line width=1pt]
\def\scalefactor{1}
\begin{tikzpicture}
\pgfplotsset{cycle list name=exotic}
 \kiviat{table2.dat} 
\end{tikzpicture}

\end{document

Spider diagrams with pgfplots

share|improve this answer
add comment

AFAIK you have to use the transform canvas option to scale complex tikzpictures, e.g. [transform canvas={scale=2}], otherwise only the coordinates are scaled. See section 22.4 "Canvas Transformations" in the pgfmanual.

You also can just put the whole picture in a \scalebox or \resizebox (graphicx package).

Update:

I tested your document now with [transform canvas={scale=2}]. The scaling seems work but the bounding box is gone. I would really suggest to use \scalebox or \resizebox as described for this question. They work fine.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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