![pgfplots 中的二项树](https://linux22.com/image/414477/pgfplots%20%E4%B8%AD%E7%9A%84%E4%BA%8C%E9%A1%B9%E6%A0%91.png)
问题
使用 pgfplots 重组树解决方案(不是纯 TikZ)。
语境
有多个关于树的帖子(这里,这里,这里等等),解决方案以多种方式被拒绝(节点矩阵、树等)。但是我没有看到解决方案pgfplots
。
在MWE
努力适应这里,我被两种绘制箭头的方法困住了。
- 第一组从左到右的箭头
- 第二组箭头从右向左
\documentclass{standalone}
\usepackage{pgfplots}
\usetikzlibrary{arrows.meta}
\begin{document}
\def\mallevel{5} % a number of levels we wish to get
\tikzset{
inner sep=0pt, outer sep=2pt, % some node reserve
malarrow/.style={->, shorten >=0pt, shorten <=-2pt, -{Stealth[length=5pt, width=3pt, inset=1pt]},
}, % a style for arrows, -2 is a shift back (an experiment)
malnode/.style={text=white,draw=blue!50, minimum width=5mm, circle, inner sep=1pt,font=\tiny,fill=blue,opacity=0.5,text opacity=1}, % a style for nodes
}
\begin{tikzpicture}
\begin{axis}[
xmin = 0,
xmax = \mallevel,
ymin = -\mallevel,
ymax = \mallevel,
xlabel = $x$,
yticklabel=\empty,
y axis line style={draw=none},
clip=false,
]
\foreach \x in {0,...,\mallevel}
{
\foreach \y in {0,...,\x}
{
\pgfmathparse{-\x/2+\y} % move up by a half of a tree (vertical direction)
\let\movey=\pgfmathresult
\edef\temp{\noexpand
\node[malnode] (\x-\y) at (axis cs:\x,\movey) {{\x}-{\y}};
}
\temp
%%%%%%%% draw the arrows %%%%%%%%
\ifnum\x>0
\pgfmathparse{int(\x-1)}
\let\previousx=\pgfmathresult % previous level (horizontal direction)
\ifnum\y>0
\pgfmathparse{int(\y-1)}
\let\previousy=\pgfmathresult % previous level (vertical direction)
% \node[malnode] (\previousx-\previousy) at (axis cs:\previousx,\previousy) {check};
% \draw[malarrow] (\previousx-\previousy) -- (\x-\y);
\fi
\fi
}
}
\end{axis}
\end{tikzpicture}
\end{document}
答案1
根据你具体在做什么,最好在 之外做这种事情axis
。但无论如何,你主要只需要重复这个\edef\temp{...}\temp
技巧。使用evaluate
可以简化代码,不需要 等\pgfmathparse
。
不知道箭头是否符合您的要求,但如果不是,您应该能够修复它。
\documentclass{standalone}
\usepackage{pgfplots}
\usetikzlibrary{arrows.meta}
\begin{document}
\def\mallevel{5} % a number of levels we wish to get
\tikzset{
inner sep=0pt, outer sep=2pt, % some node reserve
malarrow/.style={->, shorten >=0pt, shorten <=-2pt, -{Stealth[length=5pt, width=3pt, inset=1pt]},
}, % a style for arrows, -2 is a shift back (an experiment)
malnode/.style={text=white,draw=blue!50, minimum width=5mm, circle, inner sep=1pt,font=\tiny,fill=blue,opacity=0.5,text opacity=1}, % a style for nodes
}
\begin{tikzpicture}
\begin{axis}[
xmin = 0,
xmax = \mallevel,
ymin = -\mallevel,
ymax = \mallevel,
xlabel = $x$,
yticklabel=\empty,
y axis line style={draw=none},
tickwidth=0,
clip=false,
]
\foreach \x in {0,...,\mallevel}
{
\foreach [evaluate={
\movey=-\x/2+\y;
\previousy=int(\y-1);
\previousx=int(\x-1)}
] \y in {0,...,\x}
{
\edef\temp{\noexpand
\node[malnode] (\x-\y) at (axis cs:\x,\movey) {{\x}-{\y}};
}
\temp
%%%%%%%% draw the arrows %%%%%%%%
\ifnum\x>0
\ifnum\y>0
\edef\temp{%
\noexpand\draw[malarrow] (\previousx-\previousy) -- (\x-\y);
\noexpand\draw[malarrow] (\previousx-\previousy) -- (\x-\previousy);
}
\temp
\fi
\fi
}
}
\end{axis}
\end{tikzpicture}
\end{document}