考虑三维散点图中的点,例如以下:
\documentclass{article}
\usepackage{pgfplots}
\usepackage{datatool}
\DTLloaddb[noheader=false]{coordinates}{data.csv}
\pgfplotsset{compat=1.12}
\usepackage{filecontents}
\begin{filecontents*}{data.csv}
xc,yc,xer,yer,phi
1,4,0.04,0.02,0.5
2,3,0.87,0.24,1
3,5,0.02,0.3,2.35
4,1,0.4,0.9,2.5
5,3,0.2,0.1,0.2
2.5,3,1.2,0.5,0.2
3,2,1,0.25,2.3
\end{filecontents*}
\begin{document}
\begin{tikzpicture}
\def\Xmin{0}
\def\Ymin{-0.5}
\begin{axis}[
xmin=\Xmin,
ymin=\Ymin,
]
\addplot table [x=xc, y=yc, col sep=comma, only marks, mark=0] {data.csv};
\pgfplotsextra{\DTLforeach*{coordinates}{\x=xc, \y=yc,\xr=xer,\yr=yer,\an=phi}{
\filldraw[blue,fill opacity=0.2]
(axis cs:\x,\y) ellipse [x radius=\xr,y radius=\yr,rotate around={deg(\an):(\Xmin,\Ymin)}];
}
}
\end{axis}
\end{tikzpicture}
\end{document}
我的问题是如何围绕该图中指定的一组点绘制凸 3d 形状(非标准形状)?
答案1
\documentclass{article}
\usepackage{pgfplots}
\usepackage{datatool}
\DTLloaddb[noheader=false]{coordinates}{data.csv}
\pgfplotsset{compat=1.12}
% pgfmanual p. 1087
\pgfdeclareradialshading{ellipseshading}{\pgfpoint{-10bp}{10bp}}
{color(0bp)=(cyan!15!white); color(9bp)=(cyan!75!white);
color(18bp)=(cyan!70!black); color(25bp)=(cyan!50!black); color(50bp)=(black)}
\pgfdeclareplotmark{elli}{\pgfpathellipse{\pgfpointorigin}{\pgfpoint{2mm}{0cm}}{\pgfpoint{0cm}{3.5mm}}
\pgfshadepath{ellipseshading}{0}
\pgfusepath{}}
\makeatletter
\pgfkeyssetvalue{/tikz/convex hull}{\let\tikz@plot@handler=\pgfplothandlerconvexhull}
\pgfdeclareplothandler{\pgfplothandlerconvexhull}{}{
start = {\pgf@plot@mark@count = 1},
point = {\pgfcoordinate{convex hull-\the\pgf@plot@mark@count}{##1}\global\advance\pgf@plot@mark@count by1\relax},
end = {% Find the top point
\pgfmathtruncatemacro\pgf@ch@total{\the\pgf@plot@mark@count-1}%
\pgf@plot@mark@count = 0\pgfmathtruncatemacro\xe{int(\pgf@ch@total-1)}%
\foreach\x in{1,...,\xe}{%
\def\pgf@ch@invalid@flag{0}\pgfmathtruncatemacro\xx{int(\x+1)}%
\foreach\y in{\xx,...,\pgf@ch@total}{%
\pgfmathanglebetweenpoints{\pgfpointanchor{convex hull-\x}{center}}%
{\pgfpointanchor{convex hull-\y}{center}}%
%\typeout{current test \x - \y : angle \pgfmathresult}
\ifdim 180pt >\pgfmathresult pt\relax\xdef\pgf@ch@invalid@flag{1}\breakforeach\fi%
}%
\ifnum\pgf@ch@invalid@flag<1\relax\xdef\pgf@ch@first@{\x}\breakforeach\else%
\xdef\pgf@ch@first@{\pgf@ch@total}\fi%
}% Found. Now look at upperright then switch to that and rotate...loop
\edef\pgf@ch@current@{\pgf@ch@first@}\def\pgf@ch@current@angle{0}%
\edef\pgf@ch@collected{\pgf@ch@first@}\def\pgf@ch@temp@max@{0}%
\foreach\x in {1,...,\pgf@ch@total}{
\pgftransformshift{\pgfpointdiff{\pgfpointorigin}%
{\pgfpointanchor{convex hull-\pgf@ch@current@}{center}}}%
\pgftransformrotate{\pgf@ch@current@angle-360}%
\pgfmathloop%
\ifnum\pgfmathcounter=\pgf@ch@current@\relax\else%
\pgfmathanglebetweenpoints{\pgfpointanchor{convex hull-\pgf@ch@current@}{center}}%
{\pgfpointanchor{convex hull-\pgfmathcounter}{center}}%
\edef\pgf@ch@current@angle{\pgfmathresult}%
\ifdim\pgf@ch@current@angle pt>\pgf@ch@temp@max@ pt\relax%
\edef\pgf@ch@temp@max@{\pgf@ch@current@angle}%
\edef\pgf@ch@temp@current@{\pgfmathcounter}%
%\typeout{new max for \pgf@ch@current@ with \the\c@pgf@countd: angle \pgf@ch@current@angle}
\fi%
\fi%
\ifnum\pgfmathcounter<\pgf@ch@total\repeatpgfmathloop%
\xdef\pgf@ch@current@angle{\pgf@ch@temp@max@}%
\xdef\pgf@ch@current@{\pgf@ch@temp@current@}%
\expandafter\xdef\expandafter\pgf@ch@collected\expandafter{\pgf@ch@collected,\pgf@ch@current@}%
\ifnum\pgf@ch@current@=\pgf@ch@first@\relax\breakforeach\fi%
%\typeout{\pgf@ch@collected}
}%
\foreach\x[count=\xi] in\pgf@ch@collected{%
\ifnum\xi=1\relax\pgfpathmoveto{\pgfpointanchor{convex hull-\x}{center}}\else%
\pgfpathlineto{\pgfpointanchor{convex hull-\x}{center}}\fi%
}\pgfpathclose%
}
}
\makeatother
\usepackage{filecontents}
\begin{filecontents*}{data.csv}
xc,yc,xer,yer,phi
1,4,0.04,0.02,0.5
2,3,0.87,0.24,1
3,5,0.02,0.3,2.35
4,1,0.4,0.9,2.5
5,3,0.2,0.1,0.2
2.5,3,1.2,0.5,0.2
3,2,1,0.25,2.3
\end{filecontents*}
\begin{document}
\begin{tikzpicture}
\def\Xmin{0}
\def\Ymin{-0.5}
\begin{axis}[
xmin=\Xmin,
ymin=\Ymin,
]
\addplot[only marks, mark=*] table [x=xc, y=yc, col sep=comma] {data.csv};
%\addplot[only marks, mark=elli,opacity=0.7] table [x=xc, y=yc, col sep=comma] {data.csv};
\addplot[/tikz/convex hull] table [x=xc, y=yc, col sep=comma] {data.csv};
% \pgfplotsextra{\DTLforeach*{coordinates}{\x=xc, \y=yc,\xr=xer,\yr=yer,\an=phi}{
% \filldraw[blue,fill opacity=0.2]
% (axis cs:\x,\y) ellipse [x radius=\xr,y radius=\yr,rotate around={deg(\an):(\Xmin,\Ymin)}];
% }
% }
\end{axis}
\end{tikzpicture}
\end{document}
我不确定这是你想要的。(而且你的第二个方法\addplot
没有奏效。我添加了一个替代方案,我声明了一个情节标记来生成一些我认为可能是你想要的东西。)