雷达图 - 轴问题

雷达图 - 轴问题

我在绘制雷达图时遇到了一些问题。

我想要绘制下面的图表。

在此处输入图片描述

我尝试粘贴在这里和那里找到的代码片段(我知道这不是一个好方法)并得到了以下结果。

在此处输入图片描述

有什么建议吗?

我花了一周的时间尝试做这件事。提前感谢您的帮助!!

使用的数据为:

colonna1 colonna2 
4 12 
3 2 
.02 .1 

代码如下:

\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}

使用以下命令:

\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

解决了:

\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}

答案1

你可以用 绘制这个形状tikz-3dplot。这是最终结果

在此处输入图片描述

我在 x 和 y 数据中添加了比例变量,以便您可以更改它们。

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

如果您想放大或缩小,请更改它们。这是适合您的情况的代码。

\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}

相关内容