使用 tikzmark 在表格上绘制箭头

使用 tikzmark 在表格上绘制箭头

我尝试使用 tikz 和 tikzmark 让线条沿表格中的条目对角线绘制,但 tikz 并未在表格中的文本上方绘制。我该如何修复此问题?我希望继续使用适当的数学结构(如表格),而不是更改为 pgf 特定的结构,只需在顶部绘制一条线,就像用于证明有理数可数性的线一样,如下所示:https://plus.maths.org/issue47/features/macgregor/diagram3.gif但最好在末端有一个箭头。有什么好办法吗?

\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[margin=1in]{geometry}
\usepackage{amsmath,amsfonts,amssymb,amsthm}
\usepackage{comment}
\usepackage{tikz}

\begin{document}

\begin{tabular}{c c c c c c}
$(1,1)$ & $(1,2)$ & $(1,3)$ & $(1,4)$ & $(1,5)$ & $\cdots$ \\
$(2,1)$ & $(2,2)$ & $(2,3)$ & $(2,4)$ & $(2,5)$ & $\cdots$ \\
$(3,1)$ & $(3,2)$ & $(3,3)$ & $(3,4)$ & $(3,5)$ & $\cdots$ \\
$(4,1)$ & $(4,2)$ & $(4,3)$ & $(4,4)$ & $(4,5)$ & $\cdots$ \\
$(5,1)$ & $(5,2)$ & $(5,3)$ & $(5,4)$ & $(5,5)$ & $\cdots$ \\
$\vdots$ & $\vdots$ & $\vdots$ & $\vdots$ & $\vdots$ & $\ddots$ \\
\end{tabular}

\newcommand {\tikzmark}[2]{%
    \tikz[overlay,remember picture] \node (#1) {#2};
}

\begin{tabular}{c c c c c c}
\tikzmark{1-1}{$(1,1)$} & \tikzmark{1-2}{$(1,2)$} & \tikzmark{1-3}{$(1,3)$} & \tikzmark{1-4}{$(1,4)$} & \tikzmark{1-5}{$(1,5)$} & $\cdots$ \\
\tikzmark{2-1}{$(2,1)$} & $(2,2)$ & $(2,3)$ & $(2,4)$ & $(2,5)$ & $\cdots$ \\
\tikzmark{3-1}{$(3,1)$} & $(3,2)$ & $(3,3)$ & $(3,4)$ & $(3,5)$ & $\cdots$ \\
\tikzmark{4-1}{$(4,1)$} & $(4,2)$ & $(4,3)$ & $(4,4)$ & $(4,5)$ & $\cdots$ \\
\tikzmark{5-1}{$(5,1)$} & $(5,2)$ & $(5,3)$ & $(5,4)$ & $(5,5)$ & $\cdots$ \\
$\vdots$ & $\vdots$ & $\vdots$ & $\vdots$ & $\vdots$ & $\ddots$ \\
\end{tabular}

\tikz[overlay,remember picture]
\draw [->,overlay,remember picture,xshift=20ex] (1-1) -- (2-1) -- (1-2) -- (1-3) -- (3-1) -- (4-1) -- (1-4) -- (1-5);

\end{document}

答案1

由于您需要一些数学环境,我推荐arraymatrix(来自amsmath)。该线可以绘制为坐标之间的图。我还对\tikzmark命令做了一些小改动,以便在编写矩阵时获得更好的概览。

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[margin=1in]{geometry}
\usepackage{amsmath,amsfonts,amssymb,amsthm}
\usepackage{comment}
\usepackage{tikz}

\newcommand{\tikzmark}[2]{\tikz[remember picture] \node (#1-#2) {$(#1,#2)$};}
%%
\begin{document}

\begin{displaymath}
  \begin{matrix}
    \tikzmark{1}{1} & \tikzmark{1}{2} & \tikzmark{1}{3} & \tikzmark{1}{4} & \tikzmark{1}{5} & \cdots\\
    \tikzmark{2}{1} & \tikzmark{2}{2} & \tikzmark{2}{3} & \tikzmark{2}{4} & \tikzmark{2}{5} & \cdots\\
    \tikzmark{3}{1} & \tikzmark{3}{2} & \tikzmark{3}{3} & \tikzmark{3}{4} & \tikzmark{3}{5} & \cdots\\
    \tikzmark{4}{1} & \tikzmark{4}{2} & \tikzmark{4}{3} & \tikzmark{4}{4} & \tikzmark{4}{5} & \cdots\\
    \tikzmark{5}{1} & \tikzmark{5}{2} & \tikzmark{5}{3} & \tikzmark{5}{4} & \tikzmark{5}{5} & \cdots\\
    \vdots & \vdots & \vdots & \vdots & \vdots & \ddots
  \end{matrix}
\end{displaymath}

\begin{tikzpicture}[overlay,remember picture]
  \draw[->] plot coordinates {(1-1) (2-1) (1-2) (1-3) (3-1) (4-1) (1-4) (1-5) (5-1)};
\end{tikzpicture}

\end{document}

在此处输入图片描述

答案2

在您的代码中,这些线只是连接您的节点 (x,y)。要连接这些线,您必须将它们从中心画到中心:

\draw [->,overlay,remember picture,xshift=20ex] (1-1.center) -- (2-1.center) -- (1-2.center) -- (1-3.center) -- (3-1.center) -- (4-1.center) -- (1-4.center) -- (1-5.center);

结果是:在此处输入图片描述

对齐效果不是很好。如果您没有特别的理由使用表格,我建议您使用数组:

\documentclass[10pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[margin=1in]{geometry}
\usepackage{amsmath,amsfonts,amssymb,amsthm}
\usepackage{comment}
\usepackage{tikz}


\newcommand {\tikzmark}[2]{%
    \tikz[overlay,remember picture] \node (#1) {#2};}
\begin{document}
\[
\begin{array}{*6{c}}
(1,1) & (1,2) & (1,3) & (1,4) & (1,5) & \cdots \\
(2,1) & (2,2) & (2,3) & (2,4) & (2,5) & \cdots \\
(3,1) & (3,2) & (3,3) & (3,4) & (3,5) & \cdots \\
(4,1) & (4,2) & (4,3) & (4,4) & (4,5) & \cdots \\
(5,1) & (5,2) & (5,3) & (5,4) & (5,5) & \cdots \\
\vdots & \vdots & \vdots & \vdots & \vdots & \ddots \\
\end{array}
\]


\[
\begin{array}{*6{c}}
\tikzmark{1-1}{(1,1)} & \tikzmark{1-2}{(1,2)} & \tikzmark{1-3}{(1,3)} & \tikzmark{1-4}{(1,4)} & \tikzmark{1-5}{(1,5)} & \cdots \\
\tikzmark{2-1}{(2,1)} & \tikzmark{2-2}{(2,2)} & \tikzmark{2-3}{(2,3)} & (2,4) & (2,5) & \cdots \\
\tikzmark{3-1}{(3,1)} & \tikzmark{3-2}{(3,2)} & (3,3) & (3,4) & (3,5) & \cdots \\
\tikzmark{4-1}{(4,1)} & (4,2) & (4,3) & (4,4) & (4,5) & \cdots \\
\tikzmark{5-1}{(5,1)} & (5,2) & (5,3) & (5,4) & (5,5) & \cdots \\
\vdots & \vdots & \vdots & \vdots & \vdots & \ddots \\
\end{array}
\]

\tikz[overlay,remember picture]
\draw[->,overlay,remember picture] (1-1.center) -- (2-1.center) -- (1-2.center) -- (1-3.center) -- (2-2.center) -- (3-1.center) -- (4-1.center) -- (3-2.center) -- (2-3.center) -- (1-4.center) -- (1-5.center);

\end{document}

结果好多了: 在此处输入图片描述

遗憾的是,它不能完全解决条目间距不等的问题。我认为这与将某些条目设为节点而将某些条目设为非节点有关,但我对此并不确定。

答案3

使用{NiceArray}nicematrix该环境类似于经典的{array}( array),但在单元格、行和列下创建 PGF/Tikz 节点。可以使用这些节点在\CodeAfter环境中使用 Tikz 绘制您想要的任何规则。

\documentclass{article}
\usepackage{nicematrix,tikz}

\begin{document}

\renewcommand{\arraystretch}{1.4}
$\begin{NiceMatrix}
(1,1)  & (1,2)  & (1,3)  & (1,4)  & (1,5)  & \dots  \\
(2,1)  & (2,2)  & (2,3)  & (2,4)  & (2,5)  & \dots  \\
(3,1)  & (3,2)  & (3,3)  & (3,4)  & (3,5)  & \dots  \\
(4,1)  & (4,2)  & (4,3)  & (4,4)  & (4,5)  & \dots  \\
(5,1)  & (5,2)  & (5,3)  & (5,4)  & (5,5)  & \dots  \\
\vdots & \vdots & \vdots & \vdots & \vdots & \ddots \\
\CodeAfter
  \tikz \draw [->]
                 (1-1.center) 
              -- (2-1.center) 
              -- (1-2.center) 
              -- (1-3.center) 
              -- (3-1.center) 
              -- (4-1.center) 
              -- (1-4.center) 
              -- (1-5.center) 
              -- (5-1.center) ;
\end{NiceMatrix}$

\end{document}

您需要多次编译(因为nicematrix在后台使用 PGF/Tikz 节点)。

上述代码的输出

答案4

指出的对齐问题西弗林邦是由于overlay水平对齐的选项和垂直对齐的节点锚点。

您可以通过使用以下命令绘制由命令overlay创建的框来查看问题原始代码中的效果:tikzmarkfbox

\newcommand {\tikzmark}[2]{%
    \setlength{\fboxsep}{0pt}\fbox{\tikz[overlay,remember picture] \node (#1) {#2};}
}

在此处输入图片描述

单元格的tikzmark宽度和高度均为零,并且该空框与带有普通文本的单元格对齐。如果overlay删除该选项:

\newcommand {\tikzmark}[2]{%
    \setlength{\fboxsep}{0pt}\fbox{\tikz[remember picture] \node (#1) {#2};}
}

在此处输入图片描述

现在tikz命令会创建一个被环境考虑的框tabular。水平对齐并不完美,因为tikzmark命令的定义在末尾包含一个回车符,它相当于一个空格(你可以用 删除它%)。此外,node默认情况下,由 创建的框相对于节点内容的边距为 0.33em。可以通过inner sep选项修改此距离:

\newcommand {\tikzmark}[2]{%
    \setlength{\fboxsep}{0pt}{\tikz[remember picture] \node[inner sep=0pt] (#1) {#2};}%
}

在此处输入图片描述

垂直对齐取决于 tikz 创建的框与周围文本基线的对齐方式。如果没有任何特殊选项,tikz 创建的框将位于周围文本基线的正上方(其深度为零)。

在此处输入图片描述

您可以使用选项进行更改baseline,该选项定义 tikz 图片中的哪个点将固定基线:

\newcommand {\tikzmark}[2]{%
    \setlength{\fboxsep}{0pt}\fbox{\tikz[remember picture, baseline=(#1.base)] \node[inner sep=0pt] (#1) {#2};}%
}

在此处输入图片描述

最后,如果线必须连接节点中心,则可以使用斯蒂芬或者在tikzmark命令上定义两个节点:一个用于参考,一个用于文本,

\newcommand {\tikzmark}[2]{%
    \tikz[remember picture, baseline=(A.base)] \draw coordinate (#1) node[inner sep=0pt] (A) {#2};%
}

在此处输入图片描述

相关内容