第二轮

第二轮

我的目标是从数据集创建极坐标图,其中附加数据列定义从中心向外径向填充的颜色。这可以在 PGFPlots 中完成吗?

在下面的示例中,我创建了一个三列数据集,其中 x 是角度,y 是测量值,z 是我想通过着色包含的附加测量值。示例编译后,散点图中的标记颜色会发生变化。就着色而言,这就是我的目标:

\documentclass{standalone}
\usepackage{pgfplots}

\usepgfplotslibrary{polar}

\usepackage{filecontents}
\def\mydata{mydata.csv}
\begin{filecontents*}{\mydata}
    x,y,z
    -80,5,0
    -60,6,1
    -40,2,2
    -20,7,3
    0,5,4
    20,3,5
    40,7,6
    60,3,7
    80,4,8
\end{filecontents*}

\begin{document}

\begin{tikzpicture} 

\begin{polaraxis}[
    % x-axis
    xtick={-90, -45, 0, 45, 90},
    % y-axis
    ytick = {40, 80},
    % limits
    domain = -90:90, xmin = -90, xmax = 90,
    % colors
    colormap/viridis,
    point meta min = 0, point meta max = 8,
]
\addplot[point meta = explicit, scatter, polar comb] table [x=x, y=y, meta=z, col sep=comma] {\mydata};
\end{polaraxis}

\end{tikzpicture}

\end{document}

我的目标不是给标记着色,而是从原点到 y 值填充该颜色,就像饼图一样。“极坐标梳”看起来很有希望,但我无法给梳线着色(只有标记),梳子也无法填充线条之间(即填充整个段)。我尝试了各种[fill=...]选项,\addplot但只能得到单一颜色填充。

答案1

我认为没有pgfplots内置类似的东西。可以手动执行此操作,如下例所示,通过使用来自的宏从表中读取值pgfplotstable,然后使用普通的 TikZ 绘制图表。我从中获得了从颜色图中提取颜色的方法https://tex.stackexchange.com/a/340346

\documentclass{standalone}
\usepackage{xfp}
\usepackage{pgfplotstable} 
\usepackage{filecontents}
\def\mydata{mydata.csv}
\begin{filecontents*}{\mydata}
    x,y,z
    -80,5,0
    -60,6,1
    -40,2,2
    -20,7,3
    0,5,4
    20,3,5
    40,7,6
    60,3,7
    80,4,8
\end{filecontents*}



\pgfplotstableread[col sep=comma]{\mydata}\loadedtable

\begin{document}

\begin{tikzpicture}[
  % radii are normalized to [0,1], so the scale will in effect set the radius of the longest slice
  scale=5,
  % from https://tex.stackexchange.com/a/340346
  % Defines the colormap
  /pgfplots/colormap/viridis,
  slice/.style={/utils/exec={
     % Defines a color "mapped color"
     \pgfplotscolormapdefinemappedcolor{#1}},
     fill=mapped color
  }
 ]

% define half angle step 
\pgfmathsetmacro\Dhalf{10}

% get number of data rows in table
\pgfplotstablegetrowsof{\mydata}
\pgfmathtruncatemacro{\Nrows}{\pgfplotsretval-1}

% find min/max of z-column
\pgfmathsetmacro\ZMax{-1e3}
\pgfmathsetmacro\ZMin{1e3}
% https://tex.stackexchange.com/a/252360/
\pgfplotstableforeachcolumnelement{z}\of\loadedtable\as\cellValue{\pgfmathsetmacro{\ZMax}{max(\ZMax,\cellValue)}}
\pgfplotstableforeachcolumnelement{z}\of\loadedtable\as\cellValue{\pgfmathsetmacro{\ZMin}{min(\ZMin,\cellValue)}}
% calculate range of z-values
\pgfmathsetmacro\Zrange{\ZMax-\ZMin}

% find max radius
\pgfmathsetmacro\RMax{0}
\pgfplotstableforeachcolumnelement{y}\of\loadedtable\as\cellValue{\pgfmathsetmacro{\RMax}{max(\RMax,\cellValue)}}


% draw axis and ticks
% if you want these on top of the circle sectors, move the code to the end
\pgfmathsetmacro\AxisRadius{1.1}
\draw (0,0) -- (0,\AxisRadius) arc[start angle=90,delta angle=-180,radius=\AxisRadius] -- cycle;
\foreach \A in {-90,-45,...,90}
   \draw [very thin, gray] (0,0) -- (\A:\AxisRadius*1cm+1pt) node [black, circle,anchor=\A+180]  {$\A$};


% loop over the table
\foreach \N in {0,...,\Nrows}{
   % read x-value from table
  \pgfplotstablegetelem{\N}{x}\of\loadedtable
  \pgfmathsetmacro{\tmpX}{\pgfplotsretval}
  % read y-value from table
  \pgfplotstablegetelem{\N}{y}\of\loadedtable
  \pgfmathsetmacro{\tmpY}{\pgfplotsretval/\RMax}
  % read z-value from table
  \pgfplotstablegetelem{\N}{z}\of\loadedtable
  \pgfmathsetmacro{\tmpZ}{\pgfplotsretval}
  % \pgfplotscolormapdefinemappedcolor takes a number between 0 and 1000 as input. 
  % scale the given z-value based on the range of values
  \newcommand{\tmpClr}{\fpeval{(\tmpZ-\ZMin)/\Zrange*1000}}

  % make the slice
  \fill [slice=\tmpClr] (0,0) -- (\tmpX-\Dhalf:\tmpY) arc[start angle=\tmpX-\Dhalf, delta angle=2*\Dhalf, radius=\tmpY] -- cycle;
}


\end{tikzpicture}
\end{document}

在此处输入图片描述

第二轮

\documentclass{standalone}
\usepackage{xfp}
\usepackage{pgfplotstable} 
\usepackage{filecontents}
\def\mydata{mydata.csv}
\begin{filecontents*}{\mydata}
    x,y,z
    -80,5,0
    -60,6,1
    -40,2,2
    -20,7,3
    0,5,4
    20,3,5
    40,7,6
    60,3,7
    80,4,8
\end{filecontents*}



\pgfplotstableread[col sep=comma]{\mydata}\loadedtable

\begin{document}

\begin{tikzpicture}[
  % radii are normalized to [0,1], so the scale will in effect set the radius of the longest slice
  scale=5,
  % from https://tex.stackexchange.com/a/340346
  % Defines the colormap
  /pgfplots/colormap/viridis,
  slice/.style={/utils/exec={
     % Defines a color "mapped color"
     \pgfplotscolormapdefinemappedcolor{#1}},
     fill=mapped color
  }
 ]

% define half angle step 
\pgfmathsetmacro\Dhalf{10}

% get number of data rows in table
\pgfplotstablegetrowsof{\mydata}
\pgfmathtruncatemacro{\Nrows}{\pgfplotsretval-1}

% find min/max of z-column
\pgfmathsetmacro\ZMax{-1e3}
\pgfmathsetmacro\ZMin{1e3}
% https://tex.stackexchange.com/a/252360/
\pgfplotstableforeachcolumnelement{z}\of\loadedtable\as\cellValue{\pgfmathsetmacro{\ZMax}{max(\ZMax,\cellValue)}}
\pgfplotstableforeachcolumnelement{z}\of\loadedtable\as\cellValue{\pgfmathsetmacro{\ZMin}{min(\ZMin,\cellValue)}}
% calculate range of z-values
\pgfmathsetmacro\Zrange{\ZMax-\ZMin}

% find max radius
\pgfmathsetmacro\RMax{0}
\pgfplotstableforeachcolumnelement{y}\of\loadedtable\as\cellValue{\pgfmathsetmacro{\RMax}{max(\RMax,\cellValue)}}


% draw axis and ticks
% if you want these on top of the circle sectors, move the code to the end
\pgfmathsetmacro\AxisRadius{1.05}
\draw (0,0) -- (0,\AxisRadius) arc[start angle=90,delta angle=-180,radius=\AxisRadius] -- cycle;
\foreach \A in {-80,-60,...,90}
   \draw [very thin, gray] (0,0) -- (\A:\AxisRadius*1cm+1pt) node [black, circle,anchor=\A+180]  {$\A$};


% loop over the table
\foreach [evaluate={\M=int(\N+1);\O=int(\N-1);}] \N in {0,...,\Nrows}{
   % read x-value from table
  \pgfplotstablegetelem{\N}{x}\of\loadedtable
  \pgfmathsetmacro{\tmpX}{\pgfplotsretval}
  % read y-value from table
  \pgfplotstablegetelem{\N}{y}\of\loadedtable
  \pgfmathsetmacro{\Rmid}{\pgfplotsretval/\RMax}
  % read z-value from table
  \pgfplotstablegetelem{\N}{z}\of\loadedtable
  \pgfmathsetmacro{\tmpZ}{\pgfplotsretval}
  % \pgfplotscolormapdefinemappedcolor takes a number between 0 and 1000 as input. 
  % scale the given z-value based on the range of values
  \newcommand{\tmpClr}{\fpeval{(\tmpZ-\ZMin)/\Zrange*1000}}

  \ifnum \N>0
     \pgfplotstablegetelem{\O}{y}\of\loadedtable
     \pgfmathsetmacro{\YPre}{\pgfplotsretval/\RMax}

     \pgfmathsetmacro\Rpre{0.5*sqrt(\Rmid*\Rmid + \YPre*\YPre + 2*\Rmid*\YPre*cos(\Dhalf*2))}

     \pgfmathsetmacro\AnglePre{atan2(0.5*(\Rmid*sin(\tmpX) + \YPre*sin(\tmpX-\Dhalf*2)), 0.5*(\Rmid*cos(\tmpX) + \YPre*cos(\tmpX-\Dhalf*2)))}

  \fi
  \ifnum \N<\Nrows
     \pgfplotstablegetelem{\M}{y}\of\loadedtable
     \pgfmathsetmacro{\YPost}{\pgfplotsretval/\RMax}
     \pgfmathsetmacro\Rpost{sqrt(\Rmid*\Rmid + \YPost*\YPost + 2*\Rmid*\YPost*cos(\Dhalf*2))/2}

     \pgfmathsetmacro\AnglePost{atan2(0.5*(\Rmid*sin(\tmpX) + \YPost*sin(\tmpX+\Dhalf*2)), 0.5*(\Rmid*cos(\tmpX) + \YPost*cos(\tmpX+\Dhalf*2)))}

  \fi

  \ifnum \N=0
      \fill [slice=\tmpClr] (0,0) -- (\tmpX:\Rmid) -- (\AnglePost:\Rpost) -- cycle;
  \else
     \ifnum \N=\Nrows
       \fill [slice=\tmpClr] (0,0) -- (\tmpX:\Rmid) -- (\AnglePre:\Rpre) -- cycle;
     \else
       \fill [slice=\tmpClr] (0,0) -- (\AnglePre:\Rpre) -- (\tmpX:\Rmid) -- (\AnglePost:\Rpost) -- cycle;
     \fi
   \fi
}

\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容