我正在尝试绘制一棵树来解决博弈论问题。问题是标签p1 = 0.5十字标签我。
我想调整第一级的级别距离,但是\tikzset{level distance=2cm]
命令会改变所有距离。
也试过了\tikzstyle{level 1}=[level distance=2cm]
,但是没有用。我该怎么办?
我是 TikZ 的新手(仅 2 天),因此很乐意接受任何其他评论。
\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-qtree}
\begin{document}
\tikzset{edge from parent/.style=
{draw, edge from parent path={(\tikzparentnode) -- (\tikzchildnode)}}}
\begin{tikzpicture}[grow=down] % game tree
\tikzstyle{mydot} = [circle, minimum width=2pt,fill, inner sep=0pt] % decision node style
\tikzstyle{mystart} = [circle, minimum width=3pt, fill, inner sep=0pt] % starting node style
% \tikzset{level distance=2cm} % attempt to adjust level distance
\Tree
[.\node[mystart, label=above: {N}] {};
\edge node[left] {$p_1=0.5$}; [.\node[mydot, label=above left:I] {};
\edge node[left] {$a$}; \node[mydot, label=below: {$5,1$}] {};
\edge node[right] {$b$}; [.\node[mydot, label=above right:II] {};
\edge node[left] {$m$}; \node[mydot, label=below: {$1,2$}] {};
\edge node[right] {$n$}; \node[mydot, label=below: {$2,3$}] {}; ] ]
\edge node[right] {$p_2=0.5$}; [.\node[mydot, label=above right:II] {};
\edge node[left] {$c$}; [.\node[mydot] (a) {};
\edge node[left] {$z$}; \node[mydot, label=below: {$1,0$}] {};
\edge node[right] {$t$}; \node[mydot, label=below: {$2,2$}] {}; ]
\edge node[right] {$d$}; [.\node[mydot] (b) {};
\edge node[left] {$z$}; \node[mydot, label=below: {$3,1$}] {};
\edge node[right] {$t$}; \node[mydot, label=below: {$0,0$}] {}; ] ] ]
\draw[dashed] (a)--node[label=above:I] {}(b);
\end{tikzpicture}
\end{document}
答案1
更新
虽然这是公认的答案,但tikz-qtree
在 2012 年进行了更新以允许这样做。
原始答案:
据我所知,没有一种方法可以使用 来指定特定级别的级别距离tikz-qtree
。当然,您可以使用常规tikz
方法,但通常输入效率更高。解决您的问题最简单的方法是稍微移动标签。您可以通过定位它们和tikz-qtree
来做到这一点。[above left]
[above right]
我还对您的代码进行了一些简化,这样您可以减少输入内容:您可以创建every tree node
自己的mydot
样式,然后只需覆盖起始节点的样式即可。这意味着您不需要mydot
向树中的每个节点添加命令。我还删除了[grow down]
上的规范tikzpicture
,因为这是 的默认增长方向tikz-qtree
。
\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-qtree}
\begin{document}
\begin{tikzpicture}
\tikzstyle{mydot} =
[circle, minimum width=2pt,fill, inner sep=0pt] % decision node style
\tikzstyle{mystart} =
[circle, minimum width=3pt, fill, inner sep=0pt] % starting node style
\tikzset{edge from parent/.style=
{draw,
edge from parent path={(\tikzparentnode) -- (\tikzchildnode)}},
every tree node/.style={mydot}}
% make every tree node a decision node; then you only have to override the start node
\Tree
[.\node[mystart, label=above: {N}] {};
\edge node[above left] {$p_1=0.5$}; [.\node[ label=above left:I] {};
\edge node[left] {$a$}; \node[label=below: {$5,1$}] {};
\edge node[right] {$b$}; [.\node[ label=above right:II] {};
\edge node[left] {$m$}; \node[ label=below: {$1,2$}] {};
\edge node[right] {$n$}; \node[ label=below: {$2,3$}] {}; ] ]
\edge node[above right] {$p_2=0.5$}; [.\node[ label=above right:II] {};
\edge node[left] {$c$}; [.\node[mydot] (a) {};
\edge node[left] {$z$}; \node[ label=below: {$1,0$}] {};
\edge node[right] {$t$}; \node[ label=below: {$2,2$}] {}; ]
\edge node[right] {$d$}; [.\node[] (b) {};
\edge node[left] {$z$}; \node[ label=below: {$3,1$}] {};
\edge node[right] {$t$}; \node[ label=below: {$0,0$}] {}; ] ] ]
\draw[dashed] (a)--node[label=above:I] {}(b);
\end{tikzpicture}
\end{document}
答案2
本答复中建议的修改现已纳入tikz-qtree
软件包(版本 1.2 或更高)。有关如何使用最新版本实现此目的的详细信息,请参阅文档。
(此事发生于2012年4月。)
查看代码tikz-qtree
然后它出现* 它完全重新实现了植树程序。因此,不能保证树的标准 TikZ 键能正常工作。这就是为什么level 2/.style={something}
不起作用的原因tikz-qtree
。
虽然有可能将样式和键组合在一起,以便每个节点都知道它处于哪个级别,但这似乎是对主代码的一个非常有用的补充,而且肯定更简单通过对此进行小幅修改即可实现。首先是树生成系统。树是通过递归生成的,代码目前不跟踪递归级别。幸运的是,这很容易纠正:我们需要一个新的计数,我们在树的顶部将其设置为 0,并在我们向下移动时递增。我们的增量是本地的,以确保每当我们返回到某个级别(在处理子级的子级之后)时,我们的索引都在正确的位置。
--- pgftree.tex.orig 2010-12-31 00:50:24.000000000 +0100
+++ pgftree.tex 2012-04-19 10:34:57.286252337 +0200
@@ -82,11 +82,14 @@
\newdimen\pgftree@savechildy
\newcount\pgftree@childi
\newcount\pgftree@savechildi
+\newcount\pgftree@level
%%% \pgftree{subtree}
\def\pgftree#1{%
\def\nodename{r}%
+\pgftree@level=0\relax
+\pgfkeys{/pgf/qtree/every level/.try,/pgf/qtree/level \the\pgftree@level/.try}%
#1%
\pgfplacesubpicture
}
@@ -108,6 +111,8 @@
\pgftree@savechildx=\pgftree@childx
\pgftree@savechildy=\pgftree@childy
\pgftree@savechildi=\pgftree@childi
+\advance\pgftree@level by 1\relax
+\pgfkeys{/pgf/qtree/every level/.try,/pgf/qtree/level \the\pgftree@level/.try}%
% Build subpicture with all the children and their subtrees
{\pgftree@childx=0pt%
\pgftree@childy=0pt%
现在我们可以跟踪树的级别了。根树最终处于第 1 级。
现在我们需要使用该信息根据级别执行按键。为此,我们需要在相关阶段插入一些按键处理。有几个地方可以做到这一点:直接在代码中pgftree
或在tikz-qtree
代码中。我不确定哪个看起来更自然,代码有意义的两个地方有不同的效果(一个持续只是对于级别,另一个也会对树的所有后续部分产生影响),所以我为两者添加了代码。为了与 PGF 和 TikZ 的分离保持一致,部分中的键pgftree
为 形式/pgf/qtree/level n
,部分中的tikz-qtree
键为 形式。我还通过添加一个在中附加了样式的键/tikz/level n
,提供了对较低级别 TikZ 级别的访问。/pgf/qtree/every level
tikz-qtree
/tikz,level \the\pgftree@level\space onwards
继承因素意味着,为了获得所需的风格,任何一个做:
\tikzset{level 1/.style={level distance=2cm}}
或者这样做:
\tikzset{level 1 onwards/.style={level distance=2cm}}
\tikzset{level 2 onwards/.style={level distance=1cm}}
该部分的补丁pgftree
已包含在上面。该tikz-qtree
部分内容如下:
--- tikz-qtree.tex.orig 2011-10-10 23:53:59.000000000 +0200
+++ tikz-qtree.tex 2012-04-19 10:39:02.516300095 +0200
@@ -75,9 +75,9 @@
}
\def\@@@@@@subtree{%
\@ifequal{\the\root@node}{\pgfutil@empty}%
-\edef\act{\noexpand\@result={\noexpand\pgfsubtree{\noexpand\path coordinate (\noexpand\nodename);}{\the\child@list}}}%
+\edef\act{\noexpand\@result={\noexpand\pgfsubtree{\noexpand\tikzset{level \noexpand\the\pgftree@level/.try}\noexpand\path coordinate (\noexpand\nodename);}{\the\child@list}}}%
\else
-\edef\act{\noexpand\@result={\noexpand\pgfsubtree{\the\root@node}{\the\child@list}}}%
+\edef\act{\noexpand\@result={\noexpand\pgfsubtree{\noexpand\tikzset{level \noexpand\the\pgftree@level/.try}\the\root@node}{\the\child@list}}}%
\fi
\act
\@return}
@@ -117,7 +117,7 @@
\def\@interior.{\@result{\node[alias=\nodename][every tree node,every internal node]}\@label}
\def\@leaf{\@call\@label\@@leaf}
-\def\@@leaf{\edef\act{\noexpand\@result{\noexpand\pgfsubtree{\noexpand\node[alias=\noexpand\nodename][every tree node,every leaf node]\the\@result}{}}}\act\@return}
+\def\@@leaf{\edef\act{\noexpand\@result{\noexpand\pgfsubtree{\noexpand\tikzset{level \noexpand\the\pgftree@level/.try}\noexpand\node[alias=\noexpand\nodename][every tree node,every leaf node]\the\@result}{}}}\act\@return}
\def\@edge\edge #1;{%
\@result{\edge@adapter{#1}}%
@@ -179,3 +179,4 @@
% predefined roof style
\tikzset{roof/.style={edge from parent path=\roof@edge{\tikzparentnode}{\tikzchildnode}}}
+\pgfkeys{/pgf/qtree/every level/.append style={/tikz,level \the\pgftree@level\space onwards/.try}}
我很可能错过了一些应该设置键的地方!所以请谨慎使用。
这是包含这些新密钥的代码:
\documentclass{article}
%\url{https://tex.stackexchange.com/q/39103/86}
\usepackage{tikz}
\usepackage{tikz-qtree}
\begin{document}
\tikzset{edge from parent/.style=
{draw, edge from parent path={(\tikzparentnode) -- (\tikzchildnode)}}}
\tikzset{got called/.code={\message{got called}}}
\begin{tikzpicture}[grow=down]% game tree
\tikzset{mydot/.style={circle, minimum width=2pt,fill, inner sep=0pt}} % decision node style
\tikzset{mystart/.style={circle, minimum width=3pt, fill, inner sep=0pt}} % starting node style
\Tree
[.\node[mystart, label=above: {N}] {};
\edge node[left] {$p_1=0.5$}; [.\node[mydot, label=above left:I] {};
\edge node[left] {$a$}; \node[mydot, label=below: {$5,1$}] {};
\edge node[right] {$b$}; [.\node[mydot, label=above right:II] {};
\edge node[left] {$m$}; \node[mydot, label=below: {$1,2$}] {};
\edge node[right] {$n$}; \node[mydot, label=below: {$2,3$}] {}; ] ]
\edge node[right] {$p_2=0.5$}; [.\node[mydot, label=above right:II] {};
\edge node[left] {$c$}; [.\node[mydot] (a) {};
\edge node[left] {$z$}; \node[mydot, label=below: {$1,0$}] {};
\edge node[right] {$t$}; \node[mydot, label=below: {$2,2$}] {}; ]
\edge node[right] {$d$}; [.\node[mydot] (b) {};
\edge node[left] {$z$}; \node[mydot, label=below: {$3,1$}] {};
\edge node[right] {$t$}; \node[mydot, label=below: {$0,0$}] {}; ] ] ]
\draw[dashed] (a)--node[label=above:I] {}(b);
\end{tikzpicture}
\begin{tikzpicture}[grow=down]% game tree
\tikzset{mydot/.style={circle, minimum width=2pt,fill, inner sep=0pt}} % decision node style
\tikzset{mystart/.style={circle, minimum width=3pt, fill, inner sep=0pt}} % starting node style
\tikzset{level 1/.style={level distance=2cm}}
\Tree
[.\node[mystart, label=above: {N}] {};
\edge node[left] {$p_1=0.5$}; [.\node[mydot, label=above left:I] {};
\edge node[left] {$a$}; \node[mydot, label=below: {$5,1$}] {};
\edge node[right] {$b$}; [.\node[mydot, label=above right:II] {};
\edge node[left] {$m$}; \node[mydot, label=below: {$1,2$}] {};
\edge node[right] {$n$}; \node[mydot, label=below: {$2,3$}] {}; ] ]
\edge node[right] {$p_2=0.5$}; [.\node[mydot, label=above right:II] {};
\edge node[left] {$c$}; [.\node[mydot] (a) {};
\edge node[left] {$z$}; \node[mydot, label=below: {$1,0$}] {};
\edge node[right] {$t$}; \node[mydot, label=below: {$2,2$}] {}; ]
\edge node[right] {$d$}; [.\node[mydot] (b) {};
\edge node[left] {$z$}; \node[mydot, label=below: {$3,1$}] {};
\edge node[right] {$t$}; \node[mydot, label=below: {$0,0$}] {}; ] ] ]
\draw[dashed] (a)--node[label=above:I] {}(b);
\end{tikzpicture}
\begin{tikzpicture}[grow=down]% game tree
\tikzset{mydot/.style={circle, minimum width=2pt,fill, inner sep=0pt}} % decision node style
\tikzset{mystart/.style={circle, minimum width=3pt, fill, inner sep=0pt}} % starting node style
\tikzset{level distance=2cm}
\tikzset{level 2 onwards/.style={level distance=1cm}}
\Tree
[.\node[mystart, label=above: {N}] {};
\edge node[left] {$p_1=0.5$}; [.\node[mydot, label=above left:I] {};
\edge node[left] {$a$}; \node[mydot, label=below: {$5,1$}] {};
\edge node[right] {$b$}; [.\node[mydot, label=above right:II] {};
\edge node[left] {$m$}; \node[mydot, label=below: {$1,2$}] {};
\edge node[right] {$n$}; \node[mydot, label=below: {$2,3$}] {}; ] ]
\edge node[right] {$p_2=0.5$}; [.\node[mydot, label=above right:II] {};
\edge node[left] {$c$}; [.\node[mydot] (a) {};
\edge node[left] {$z$}; \node[mydot, label=below: {$1,0$}] {};
\edge node[right] {$t$}; \node[mydot, label=below: {$2,2$}] {}; ]
\edge node[right] {$d$}; [.\node[mydot] (b) {};
\edge node[left] {$z$}; \node[mydot, label=below: {$3,1$}] {};
\edge node[right] {$t$}; \node[mydot, label=below: {$0,0$}] {}; ] ] ]
\draw[dashed] (a)--node[label=above:I] {}(b);
\end{tikzpicture}
\end{document}
以下是示例输出:
我想补充一点,Ryan Reich 的出色trace-pgfkeys
软件包对于完成上述任务绝对必不可少。特别是,它让我很容易看到标准level n
键没有得到处理,这给了我提示,让我更深入地研究代码,看看到底发生了什么。参见我如何调试 pgfkeys?了解有关此最优秀套餐的更多信息。
* 我没有仔细研究过代码,所以我的推论可能是错误的。但是,它们与我的实验结果一致,所以我准备接受它们作为工作假设。
答案3
随着istgame
包,您可以使用\xtdistance{<lev-dist>}{<sib-dist>}
它来改变级别距离和兄弟距离。
请注意,使用 tikz-qtree 包与任何其他方法在 tikz 中绘制树可能会产生意想不到的结果。因此,除非您知道自己在做什么,否则请使用only tikz-qtree
或do not use tikz-qtree
使用 TikZ 绘制树。
\documentclass{standalone}
\usepackage{istgame}
\begin{document}
\begin{istgame}[font=\footnotesize]
\xtdistance{15mm}{32mm}
\istroot(0){N}
\istb{p_1=0.5}[l]
\istb{p_2=0.5}[r]
\endist
\xtdistance{10mm}{16mm}
\istroot(1)(0-1)<135>{I}
\istb{a}[l]{5,1}[b]
\istb{b}[r]
\endist
\istroot(2)(0-2)<45>{II}
\istb{c}[l]
\istb{d}[r]
\endist
\xtdistance{10mm}{8mm}
\istroot(3)(1-2)<45>{II}
\istb{m}[l]{1,2}
\istb{n}[r]{2,3}
\endist
\istroot(3a)(2-1)
\istb{z}[l]{1,0}
\istb{t}[r]{2,2}
\endist
\istroot(3b)(2-2)
\istb{z}[l]{3,1}
\istb{t}[r]{0,0}
\endist
\xtInfoset(3a)(3b){I}
\end{istgame}
\end{document}