使用 TikZ 绘制 DNA 序列的显示问题

使用 TikZ 绘制 DNA 序列的显示问题

以下 TikZ 代码展示了 DNA 代码段的表示。

我有两个不同版本的代码。版本 1 使用多部分矩形,这是我的首选版本。版本 2 将 DNA 序列建模为粘在一起的单个方块。问题是这些方块往往会随着比例的变化而脱落,这很烦人。

部分出于这个原因,我更喜欢版本 1,但它也存在一些问题。如果这些问题无法解决,那么我将使用版本 2。

问题就在这里。

1) 左边的方块,称为方块 A,在某些地方颜色溢出了方框。特别是在右侧。例如,参见右下角,方块两侧是 $X_{9}$ 和 $X^{(6)}$。这里颜色溢出方框的情况非常明显。在其他地方也可以看到。如果

\tikzstyle{every path}=[very thick]

被删除。但是,我想要粗路径。这可能是用户错误或错误的结果。我认为这可能是 TikZ 在计算矩形各部分的尺寸时产生的舍入误差的累积结果,因为向右移动时情况会变得更糟。问题是是否有办法解决这个问题。

2)从 A 块向右的箭头应仅在终止点处有箭头,但两端都有箭头。

3)左右两侧的盒子应该对齐。它们顶部对齐,但底部不对齐。

最后,有几个严格意义上来说不算是问题的问题。

4) 有什么建议可以防止箭头遮挡标签吗?也许可以将标签设为不同的颜色?有没有简单的方法可以将标签叠加在箭头上方?

5)有没有办法使多部分矩形内的分割线与其他线条的粗细不同?

6)如何制作以

\node [below] at (leftrow6.one south) {$\mathsmaller{\mathbf{X_{0}}}$};

陷入循环?下面是一个尝试,即

\foreach \i in {one, two, three, four, five, six, seven, eight, nine, ten}
{
  \foreach \j in {0,...,9}
  {
    \node [below] at (leftrow6.\i south) {$\mathsmaller{\mathbf{X_{\j}}}$};
  }
}

但这不起作用。

以下是两个版本的代码。欢迎提出改进建议,包括减少代码行数。版本 1 的图像位于底部。

版本 1

\documentclass[a4paper, 12pt]{article}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows, positioning, calc, patterns, shadows, external}
%%%<
\usepackage{verbatim}
\usepackage{lmodern}
\usepackage{scrextend}
\usepackage{relsize}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}%
%%%>
\usetikzlibrary{chains,fit,shapes, shapes.multipart}
\begin{document}
\changefontsizes{20pt}
\begin{tikzpicture}
\tikzstyle{every path}=[very thick]
\tikzstyle{line} = [draw, -latex', thick]

\tikzstyle{seq}=[rectangle split, rectangle split horizontal, rectangle split parts=#1, minimum height=1cm, draw, anchor=center]

\matrix[row sep=0.5cm] at (0cm, 4cm)
{
\node [seq=10, rectangle split part fill={blue!20, none, cyan!30, none, blue!20, none, none, cyan!30, none, cyan!30}] (leftrow1)
{C \nodepart{two} \phantom{X} \nodepart{three} A \nodepart{four} \phantom{X} \nodepart{five} G \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} G \nodepart{nine} \phantom{X} \nodepart{ten} C}; \\

\node [seq=10, rectangle split part fill={green!20, none, orange!50, none, green!20, none, none, orange!50, none, orange!50}] (leftrow2)
{A \nodepart{two} \phantom{X} \nodepart{three} C \nodepart{four} \phantom{X} \nodepart{five} C \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} A \nodepart{nine} \phantom{X} \nodepart{ten} A}; \\

\node [seq=10, rectangle split part fill={green!20, none, yellow!50, none, green!20, none, none, yellow!50, none, yellow!50}] (leftrow3)
{A \nodepart{two} \phantom{X} \nodepart{three} T \nodepart{four} \phantom{X} \nodepart{five} C \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} T \nodepart{nine} \phantom{X} \nodepart{ten} T}; \\

\node [seq=10, rectangle split part fill={blue!20, none, cyan!30, none, blue!20, none, none, cyan!30, none, cyan!30}] (leftrow4)
{C \nodepart{two} \phantom{X} \nodepart{three} A \nodepart{four} \phantom{X} \nodepart{five} G \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} G \nodepart{nine} \phantom{X} \nodepart{ten} C}; \\

\node [seq=10, rectangle split part fill={blue!20, none, cyan!30, none, blue!20, none, none, cyan!30, none, cyan!30}] (leftrow5)
{C \nodepart{two} \phantom{X} \nodepart{three} A \nodepart{four} \phantom{X} \nodepart{five} G \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} G \nodepart{nine} \phantom{X} \nodepart{ten} C}; \\

\node [seq=10, rectangle split part fill={red!50, none, orange!50, none, red!50, none, none, orange!50, none, orange!50}] (leftrow6)
{A \nodepart{two} \phantom{X} \nodepart{three} C \nodepart{four} \phantom{X} \nodepart{five} A \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} A \nodepart{nine} \phantom{X} \nodepart{ten} A}; \\
};

\node [below] at (leftrow6.one south) {$\mathsmaller{\mathbf{X_{0}}}$};
\node [below] at (leftrow6.two south) {$\mathsmaller{\mathbf{X_{1}}}$};
\node [below] at (leftrow6.three south) {$\mathsmaller{\mathbf{X_{2}}}$};
\node [below] at (leftrow6.four south) {$\mathsmaller{\mathbf{X_{3}}}$};
\node [below] at (leftrow6.five south) {$\mathsmaller{\mathbf{X_{4}}}$};
\node [below] at (leftrow6.six south) {$\mathsmaller{\mathbf{X_{5}}}$};
\node [below] at (leftrow6.seven south) {$\mathsmaller{\mathbf{X_{6}}}$};
\node [below] at (leftrow6.eight south) {$\mathsmaller{\mathbf{X_{7}}}$};
\node [below] at (leftrow6.nine south) {$\mathsmaller{\mathbf{X_{8}}}$};
\node [below] at (leftrow6.ten south) {$\mathsmaller{\mathbf{X_{9}}}$};

%loop version does not work
%\foreach \i in {{one}, {two}, {three}, {four}, {five}, {six}, {seven}, {eight},   
%{nine}, {ten}}
%{
%  \foreach \j in {0,...,9}
% {
%    \node [below] at (leftrow6.\i south) {$\mathsmaller{\mathbf{X_{\j}}}$};
% }
%}

% loop version does not work
\foreach \i in {1,...,6}
{
  \node [right] at (leftrow\i.ten east) {$\mathsmaller{\mathbf{X^{(\i)}}}$};
}

\matrix[row sep=0.5cm] at (10cm, 4cm)
{
\node [seq=2, rectangle split part fill={blue!20, blue!20}] (tupletoprow)
{C \nodepart{two} G}; \\
\node [seq=2, rectangle split part fill={green!20, green!20}]
{A \nodepart{two} C}; \\
\node [seq=2, rectangle split part fill={green!20, green!20}]
{A \nodepart{two} C}; \\
\node [seq=2, rectangle split part fill={blue!20, blue!20}]
{C \nodepart{two} G}; \\
\node [seq=2, rectangle split part fill={blue!20, blue!20}]
{C \nodepart{two} G}; \\
\node [seq=2, rectangle split part fill={red!50, red!50}] (tuplebottomrow)
{A \nodepart{two} A}; \\
};

\matrix[row sep=0.5cm] at (13cm, 4cm)
{
  \node [seq=3, rectangle split part fill={cyan!30, cyan!30}] (tripletoprow)
  {A \nodepart{two} G \nodepart{three} C}; \\
  \node [seq=3, rectangle split part fill={orange!50, orange!50}]
  {C \nodepart{two} A \nodepart{three} A}; \\
  \node [seq=3, rectangle split part fill={yellow!50, yellow!50}]
  {T \nodepart{two} T \nodepart{three} T}; \\
  \node [seq=3, rectangle split part fill={cyan!30, cyan!30}]
  {A \nodepart{two} G \nodepart{three} C}; \\
  \node [seq=3, rectangle split part fill={cyan!30, cyan!30}]
  {A \nodepart{two} G \nodepart{three} C}; \\
 \node [seq=3, rectangle split part fill={orange!50, orange!50}]  (triplebottomrow)
  {C \nodepart{two} A \nodepart{three} A}; \\
};

\node [below] at (tuplebottomrow.south) {$(\mathsmaller{\mathbf{X_{0}}}, \mathsmaller{\mathbf{X_{4}}})$};
\node [below] at (triplebottomrow.south) {$(\mathsmaller{\mathbf{X_{3}}}, \mathsmaller{\mathbf{X_{7}}}, , \mathsmaller{\mathbf{X_{9}}})$};

\node [above] at (tupletoprow.north) {(0, 4)};
\node [above] at (tripletoprow.north) {(3, 7, 9)};

\path [line] (leftrow6.one south) edge[out=270, in=270] node {}(tuplebottomrow);
\path [line] (leftrow6.five south) edge[out=270, in=270] node {}(tuplebottomrow);

\path [line] (leftrow1.three north) edge[out=90, in=90] node {}(tripletoprow);
\path [line] (leftrow1.eight north) edge[out=90, in=90] node {}(tripletoprow);
\path [line] (leftrow1.ten north) edge[out=90, in=90] node {}(tripletoprow);

\end{tikzpicture}
\changefontsizes{12pt}
\end{document}

版本 2

\documentclass[a4paper, 12pt]{article}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows, positioning, calc, patterns, shadows, external}
\usepackage{verbatim}
\usepackage{lmodern}
\usepackage{scrextend}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}%
\usetikzlibrary{chains,fit,shapes}

\begin{document}
\changefontsizes{15pt}
\begin{tikzpicture}
\tikzstyle{every path}=[very thick]
\tikzstyle{line} = [draw, -latex', thick]
\edef\sizeseqbox{1.3cm}
\tikzstyle{seq}=[draw,minimum size=\sizeseqbox]

\matrix [row sep=3mm] at (-7, 0)
{
  \node []{}; & \node []{}; & \node [] {}; & \node []{}; & \node []{}; & \node []{}; & \node []{}; & \node []{}; & \node []{}; & \node [] {}; \\
  \node [seq, fill=blue!20]{C}; & \node [seq]{}; & \node [seq, fill=cyan!30] (triplecol1left) {A}; & \node [seq]{}; & \node [seq, fill=blue!20]{G}; & \node [seq]{}; & \node [seq]{}; & \node [seq, fill=cyan!30] (triplecol2left) {G}; & \node [seq]{}; & \node [seq, fill=cyan!30] (triplecol3left) {C}; & \node [] {$\mathbf{X^{(1)}}$};\\
  \node [seq, fill=green!20]{A}; & \node [seq]{}; & \node [seq, fill=orange!50]{C}; & \node [seq]{}; & \node [seq, fill=green!20]{C}; & \node [seq]{}; & \node [seq]{}; & \node [seq, fill=orange!50]{A}; & \node [seq]{}; & \node [seq, fill=orange!50]{A}; & \node [] {$\mathbf{X^{(2)}}$};\\
  \node [seq, fill=green!20]{A}; & \node [seq]{}; & \node [seq, fill=yellow!50]{T}; & \node [seq]{}; & \node [seq, fill=green!20]{C}; & \node [seq]{}; & \node [seq]{}; & \node [seq, fill=yellow!50]{T}; & \node [seq]{}; & \node [seq, fill=yellow!50]{T}; & \node [] {$\mathbf{X^{(3)}}$};\\
  \node [seq, fill=blue!20]{C}; & \node [seq]{}; & \node [seq, fill=cyan!30]{A}; & \node [seq]{}; & \node [seq, fill=blue!20]{G}; & \node [seq]{}; & \node [seq]{}; & \node [seq, fill=cyan!30]{G}; & \node [seq]{}; & \node [seq, fill=cyan!30]{C}; & \node [] {$\mathbf{X^{(4)}}$};\\
  \node [seq, fill=blue!20]{C}; & \node [seq]{}; & \node [seq, fill=cyan!30]{A}; & \node [seq]{}; & \node [seq, fill=blue!20]{G}; & \node [seq]{}; & \node [seq]{}; & \node [seq, fill=cyan!30]{G}; & \node [seq]{}; & \node [seq, fill=cyan!30]{C}; & \node [] {$\mathbf{X^{(5)}}$};\\
  \node [seq, fill=red!50] (tuplecol1left) {A}; & \node [seq]{}; & \node [seq, fill=orange!50] {C}; & \node [seq]{}; & \node [seq, fill=red!50] (tuplecol2left)  {A}; & \node [seq]{}; & \node [seq]{}; & \node [seq, fill=orange!50] {A}; & \node [seq]{}; & \node [seq, fill=orange!50] {A}; & \node [] {$\mathbf{X^{(6)}}$};\\
  \node []{$\mathbf{X_{0}}$}; & \node []{$\mathbf{X_{1}}$}; & \node [] {$\mathbf{X_{2}}$}; & \node []{$\mathbf{X_{3}}$}; & \node []{$\mathbf{X_{4}}$}; & \node []{$\mathbf{X_{5}}$}; & \node []{$\mathbf{X_{6}}$}; & \node []{$\mathbf{X_{7}}$}; & \node []{$\mathbf{X_{8}}$}; & \node [] {$\mathbf{X_{9}}$}; \\
};

\matrix [row sep=3mm] at (5, 0)
{
 \node [] {(0,}; & \node [] {4)}; \\
  \node [seq, fill=blue!20]{C}; & \node [seq, fill=blue!20]{G}; \\
  \node [seq, fill=green!20]{A}; & \node [seq, fill=green!20]{C}; \\
  \node [seq, fill=green!20]{A}; & \node [seq, fill=green!20]{C}; \\
  \node [seq, fill=blue!20]{C}; & \node [seq, fill=blue!20]{G}; \\
  \node [seq, fill=blue!20]{C}; & \node [seq, fill=blue!20]{G}; \\
  \node [seq, fill=red!50] (tuplecol1right) {A}; & \node [seq, fill=red!50] (tuplecol2right) {A}; \\
  \node [] {$(\mathbf{X_0},$}; & \node [] {$\mathbf{X_4})$}; \\
};

\matrix [row sep=3mm] at (9, 0)
{
  \node [] {(2,};                 & \node [] {7,};                   & \node [] {9)};                   \\
  \node [seq, fill=cyan!30] (triplecol1right) {A}; & \node [seq, fill=cyan!30]  (triplecol2right) {G}; & \node [seq, fill=cyan!30] (triplecol3right) {C}; \\
  \node [seq, fill=orange!50]{C}; & \node [seq, fill=orange!50]{A}; & \node [seq, fill=orange!50]{A}; \\
  \node [seq, fill=yellow!50]{T}; & \node [seq, fill=yellow!50]{T}; & \node [seq, fill=yellow!50]{T}; \\
  \node [seq, fill=cyan!30]{A};   & \node [seq, fill=cyan!30]{G};   & \node [seq, fill=cyan!30]{C};   \\
  \node [seq, fill=cyan!30]{A};   & \node [seq, fill=cyan!30]{G};   & \node [seq, fill=cyan!30]{C};   \\
  \node [seq, fill=orange!50] {C};& \node [seq, fill=orange!50] {A};& \node [seq, fill=orange!50] {A};\\
  \node [] {($\mathbf{X_2},$};                   & \node [] {$\mathbf{X_7},$};                   & \node [] {$\mathbf{X_9})$};                   \\
};

\path [line] (tuplecol1left) edge[out=270, in=270] node {}(tuplecol1right.south east);
\path [line] (tuplecol2left) edge[out=270, in=270] node {}(tuplecol2right.south west);

\path [line] (triplecol1left) edge[out=90, in=90] node {}(triplecol2right);
\path [line] (triplecol2left) edge[out=90, in=90] node {}(triplecol2right);
\path [line] (triplecol3left) edge[out=90, in=90] node {}(triplecol2right);

\end{tikzpicture}
\changefontsizes{12pt}
\end{document}

在此处输入图片描述

答案1

1)和3)在填充矩形部分时更改none为。white

2)将线条的立柱改为仅在一端有箭头(我不确定您想更改哪一个,因此我选择了底部的两个)。

4)一种可能性是先画箭头,然后放置标签(如果需要,可以垂直移动它们一点点)。

6) 循环已修复。

此外,我将旧\tikzstyle语法更改为新语法\tikzset

\documentclass[a4paper, 12pt]{article}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows, positioning, calc, patterns, shadows, external}
%%%<
\usepackage{verbatim}
\usepackage{lmodern}
\usepackage{scrextend}
\usepackage{relsize}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}%
%%%>
\usetikzlibrary{chains,fit,shapes, shapes.multipart}

\begin{document}
\changefontsizes{20pt}
\begin{tikzpicture}
\tikzset{
  every path/.style={very thick},
  line/.style={draw, -latex', thick},
  seq/.style={rectangle split,
    rectangle split horizontal,
    rectangle split parts=#1,
    minimum height=1cm,
    draw, anchor=center}
}

\matrix[row sep=0.5cm] at (0cm, 4cm)
{
\node [seq=10, rectangle split part fill={blue!20,white, cyan!30,white, blue!20, white, white, cyan!30,white,cyan!30}] (leftrow1)
{C \nodepart{two} \phantom{X} \nodepart{three} A \nodepart{four} \phantom{X} \nodepart{five} G \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} G \nodepart{nine} \phantom{X} \nodepart{ten} C}; \\

\node [seq=10, rectangle split part fill={green!20, white, orange!50, white, green!20, white, white, orange!50, white, orange!50}] (leftrow2)
{A \nodepart{two} \phantom{X} \nodepart{three} C \nodepart{four} \phantom{X} \nodepart{five} C \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} A \nodepart{nine} \phantom{X} \nodepart{ten} A}; \\

\node [seq=10, rectangle split part fill={green!20, white, yellow!50, white, green!20, white, white, yellow!50, white, yellow!50}] (leftrow3)
{A \nodepart{two} \phantom{X} \nodepart{three} T \nodepart{four} \phantom{X} \nodepart{five} C \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} T \nodepart{nine} \phantom{X} \nodepart{ten} T}; \\

\node [seq=10, rectangle split part fill={blue!20, white, cyan!30, white, blue!20, white, white, cyan!30, white, cyan!30}] (leftrow4)
{C \nodepart{two} \phantom{X} \nodepart{three} A \nodepart{four} \phantom{X} \nodepart{five} G \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} G \nodepart{nine} \phantom{X} \nodepart{ten} C}; \\

\node [seq=10, rectangle split part fill={blue!20, white, cyan!30, white, blue!20, white, white, cyan!30, white, cyan!30}] (leftrow5)
{C \nodepart{two} \phantom{X} \nodepart{three} A \nodepart{four} \phantom{X} \nodepart{five} G \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} G \nodepart{nine} \phantom{X} \nodepart{ten} C}; \\

\node [seq=10, rectangle split part fill={red!50, white, orange!50, white, red!50, white, white, orange!50, white, orange!50}] (leftrow6)
{A \nodepart{two} \phantom{X} \nodepart{three} C \nodepart{four} \phantom{X} \nodepart{five} A \nodepart{six} \phantom{X} \nodepart{seven} \phantom{X} \nodepart{eight} A \nodepart{nine} \phantom{X} \nodepart{ten} A}; \\
};

\matrix[row sep=0.5cm] at (10cm, 4cm)
{
\node [seq=2, rectangle split part fill={blue!20, blue!20}] (tupletoprow)
{C \nodepart{two} G}; \\
\node [seq=2, rectangle split part fill={green!20, green!20}]
{A \nodepart{two} C}; \\
\node [seq=2, rectangle split part fill={green!20, green!20}]
{A \nodepart{two} C}; \\
\node [seq=2, rectangle split part fill={blue!20, blue!20}]
{C \nodepart{two} G}; \\
\node [seq=2, rectangle split part fill={blue!20, blue!20}]
{C \nodepart{two} G}; \\
\node [seq=2, rectangle split part fill={red!50, red!50}] (tuplebottomrow)
{A \nodepart{two} A}; \\
};

\matrix[row sep=0.5cm] at (13cm, 4cm)
{
  \node [seq=3, rectangle split part fill={cyan!30, cyan!30}] (tripletoprow)
  {A \nodepart{two} G \nodepart{three} C}; \\
  \node [seq=3, rectangle split part fill={orange!50, orange!50}]
  {C \nodepart{two} A \nodepart{three} A}; \\
  \node [seq=3, rectangle split part fill={yellow!50, yellow!50}]
  {T \nodepart{two} T \nodepart{three} T}; \\
  \node [seq=3, rectangle split part fill={cyan!30, cyan!30}]
  {A \nodepart{two} G \nodepart{three} C}; \\
  \node [seq=3, rectangle split part fill={cyan!30, cyan!30}]
  {A \nodepart{two} G \nodepart{three} C}; \\
  \node [seq=3, rectangle split part fill={orange!50, orange!50}]  (triplebottomrow)
  {C \nodepart{two} A \nodepart{three} A}; \\
};

\path [latex'-, thick] (leftrow6.one south) edge[out=270, in=270] node {}(tuplebottomrow);
\path [latex'-, thick] (leftrow6.five south) edge[out=270, in=270] node {}(tuplebottomrow);

\path [line] (leftrow1.three north) edge[out=90, in=90] node {}(tripletoprow);
\path [line] (leftrow1.eight north) edge[out=90, in=90] node {}(tripletoprow);
\path [line] (leftrow1.ten north) edge[out=90, in=90] node {}(tripletoprow);

%loop version works
\foreach \i [count=\x] in {one ,two ,three ,four ,five ,six ,seven ,eight ,nine ,ten }
    \node [below=8pt,fill=white] at (leftrow6.\i south) {$\mathsmaller{\mathbf{X_{\x}}}$};

% loop version works
\foreach \i in {1,...,6}
{
  \node [right] at (leftrow\i.ten east) {$\mathsmaller{\mathbf{X^{(\i)}}}$};
}

\node [below=8pt,fill=white] at (tuplebottomrow.south) {$(\mathsmaller{\mathbf{X_{0}}}, \mathsmaller{\mathbf{X_{4}}})$};
\node [below=8pt,fill=white] at (triplebottomrow.south) {$(\mathsmaller{\mathbf{X_{3}}}, \mathsmaller{\mathbf{X_{7}}}, , \mathsmaller{\mathbf{X_{9}}})$};

\node [above=8pt] at (tupletoprow.north) {(0, 4)};
\node [above=8pt,fill=white] at (tripletoprow.north) {(3, 7, 9)};

\end{tikzpicture}
\changefontsizes{12pt}
\end{document}

在此处输入图片描述

答案2

不确定这是否解决了您的具体的问题,因为帖子中有很多不连贯的问题。最好将它们分成单独的问题,这样它们可能会对其他人更有帮助,也更容易回答。所以这更像是我建议你如何制作这种图表。

首先要弄清楚的是不是图表本身,而是

为了获得期望的结果,您想要指定哪些实际信息?

1.捕获数据:

因为我不是如果您对 DNA 测序有所了解,那么可能存在一种更好的方法,可以更准确地反映您的需求,但我认为每行都有三组 DNA 序列。在聊天讨论中,您提到没有一种简单的算法可以自动确定要使用的颜色,因此我看到的自然语法是这样的:

\ThreeDNASequences
    {C/cyan,, A/orange,,,G/blue,,G/red!25,,C/yellow}
    {C/violet,G/brown}
    {A/cyan,G/yellow,C/brown};

其中三个参数分别代表左、中、右序列以及颜色。多个后续逗号用于表示空单元格。因此,您需要对图表的每一行执行一次这些调用。因此,通过三个实例,您将获得三行:

在此处输入图片描述

2.画箭头:

问题的另一部分是如何在各个节点之间绘制箭头。使用类似于\tikzmark我们简单地使用计数器命名每个节点以提供对每个列的唯一引用的过程,并为宏提供一个可选参数,\ThreeDNASequences以便我们可以使用前缀来区分行。

因此,使用\ThreeDNASequences[Top]{}{}{}表示顶行,\ThreeDNASequences[Bottom]{}{}{}使用 表示底行,可以将节点标记为Top-0Top-1、... 和Bottom-0Bottom-1、...,这样我们就可以访问每个节点。由于这也有一个节点连接到多个节点的模式,因此定义一个宏是有意义的,例如:

\ConnectNodes[red, out=100, in=80]
    {Top-12.north}
    {Top-2.north,Top-7.north,Top-9.north};

指定线路的选项以及要连接的节点。

把这些放在一起,你会得到:

在此处输入图片描述

进一步增强:

  • 由于现在可以访问每个节点,因此可以使用这些节点来放置与每个节点相邻(下方、右侧或顶部)的文本。请注意,在下面的 MWE 中,我没有提供用于中间行的唯一标签,因为我并不关心需要放置的文本。因此,在放置文本时,建议您还为每行的节点标签提供唯一的前缀。
  • 如果需要的话,可能需要通过shorten语法调整箭头。
  • 使用xshift\ThreeDNASequences应该真正根据前一个序列的成员数量来计算。这实际上只有在每列的数字可能在不同的图表中发生变化时才重要。我使用\pgfmathsetmacro{\Shift}{}只是为了提供一个占位符,以表明可能需要进行这种更改的位置。

代码:

\documentclass[border=3pt]{article}
\usepackage{tikz}
\usepackage{xstring}
\usetikzlibrary{calc, arrows}

\newcommand*{\NodeSize}{0.5cm}%
\newcommand*{\YShiftBetweenRows}{-1cm}% Subsequent rows are shited down so they don't overlap
\tikzset{DNA Style/.style={minimum size=0.5cm, draw=gray, line width=1pt}}{}

\newlength{\YShift}% 
\newcounter{ColumnCounter}% Prefix for node labels

% Initialize - These are probably not needed, but prefer to set them
\setlength{\YShift}{0cm}% 
\setcounter{ColumnCounter}{0}


\newcommand*{\DNASequence}[2][Mark]{%
    % http://tex.stackexchange.com/questions/12091/tikz-foreach-loop-with-macro-defined-list
    \def\Sequence{#2}
    \foreach [count=\xi] \Label/\Color in \Sequence {%
        \pgfmathsetmacro{\XShift}{\NodeSize*\xi}%
        \IfStrEq{\Color}{}{\def\Color{white}}{}
        \edef\NodeName{#1-\arabic{ColumnCounter}}
        \node [DNA Style, fill=\Color, xshift=\XShift] (\NodeName) {\Label};
        \stepcounter{ColumnCounter}
    } 
}%


\newcommand*{\ThreeDNASequences}[4][Mark]{% #1 = tikzmark prefix
    \setcounter{ColumnCounter}{0}% reset column counter
    \begin{scope}[yshift=\YShift]
        \DNASequence[#1]{#2} 
        \pgfmathsetmacro{\Shift}{6cm}% Should compute this based on num of items in #1
        \begin{scope}[xshift=\Shift]
            \DNASequence[#1]{#3} 
        \end{scope}
        \pgfmathsetmacro{\Shift}{8cm}% Should compute this based on num of items in #2  
        \begin{scope}[xshift=\Shift]
            \DNASequence[#1]{#4} 
        \end{scope}
    \end{scope}
    \pgfmathsetlength{\YShift}{\YShift\YShiftBetweenRows}%
}

\newcommand*{\ConnectNodes}[3][]{%
    % #1 = draw options
    % #2 = ending node
    % #3 = list of starting nodes
    \def\ListOfEndNodes{#3}
    \foreach \EndNode in \ListOfEndNodes {%
    \draw[latex'-, thick, #1] (#2) to[#1] (\EndNode);
    }%
}


\begin{document}
\begin{tikzpicture}
    \ThreeDNASequences[Top]
        {C/blue!20,, A/cyan!30,,, G/blue!20,, G/cyan!30,, C/cyan!30}
        {C/blue!20, G/blue!20}
        {A/cyan!30, G/cyan!30, C/cyan!30};

    \ThreeDNASequences
        {A/green!20,, C/orange!50,,, C/green!20,, A/orange!50,, A/orange!50}
        {A/green!20, C/green!20}
        {C/orange!50, A/orange!50, A/orange!50};

    \ThreeDNASequences[Bottom]
        {C/blue!20,, A/cyan!30,,, G/blue!20,, G/cyan!30,, C/cyan!30}
        {C/blue!20, G/blue!20}
        {A/cyan!30, G/cyan!30, C/cyan!30};    

    % Now, draw the arrows as desired

\ConnectNodes[out=90, in=90]
        {Top-10.north east}
        {Top-0.north,Top-5.north};

    \ConnectNodes[out=-90, in=-90]
        {Bottom-13.south}
        {Bottom-2.south,Bottom-7.south,Bottom-9.south};  

\end{tikzpicture}
\end{document}

我再仔细看了一下图像,也许这是显示细胞合并的稍微不同的方式来:

在此处输入图片描述

只显示一侧看起来更好,但是下面的 MWE 也有顶部的代码(虽然已注释):

代码:

\documentclass[border=3pt]{article}
\usepackage{tikz}
\usepackage{xstring}
\usetikzlibrary{calc,fit,backgrounds}

\pgfdeclarelayer{background layer} 
\pgfdeclarelayer{foreground layer} 
\pgfsetlayers{background layer,main,foreground layer}

\newcommand*{\NodeSize}{0.5cm}%
\newcommand*{\YShiftBetweenRows}{-1cm}% Subsequent rows are shited down so they don't overlap
\tikzset{DNA Style/.style={minimum size=0.5cm, draw=gray, line width=1pt}}

\tikzset{Fit Line Style 1/.style={draw=olive, thick, dotted}}
\tikzset{Fill Style 1/.style={fill=olive!20}}

\tikzset{Fit Line Style 2/.style={draw=green!50!black, thick, dashed}}
\tikzset{Fill Style 2/.style={fill=green!20}}

\newlength{\YShift}% 
\newcounter{ColumnCounter}% Prefix for node labels

% Initialize - These are probably not needed, but prefer to set them
\setlength{\YShift}{0cm}% 
\setcounter{ColumnCounter}{0}


\newcommand*{\DNASequence}[2][Mark]{%
    % http://tex.stackexchange.com/questions/12091/tikz-foreach-loop-with-macro-defined-list
    \def\Sequence{#2}
    \foreach [count=\xi] \Label/\Color in \Sequence {%
        \pgfmathsetmacro{\XShift}{\NodeSize*\xi}%
        \IfStrEq{\Color}{}{\def\Color{white}}{}
        \edef\NodeName{#1-\arabic{ColumnCounter}}
        \begin{pgfonlayer}{foreground layer}
        \node [DNA Style, fill=\Color, xshift=\XShift] (\NodeName) {\Label};
        \end{pgfonlayer}
        \stepcounter{ColumnCounter}
    } 
}%


\newcommand*{\ThreeDNASequences}[4][Mark]{% #1 = tikzmark prefix
    \setcounter{ColumnCounter}{0}% reset column counter
    \begin{scope}[yshift=\YShift]
        \DNASequence[#1]{#2} 
        \pgfmathsetmacro{\Shift}{6cm}% Should compute this based on num of items in #1
        \begin{scope}[xshift=\Shift]
            \DNASequence[#1]{#3} 
        \end{scope}
        \pgfmathsetmacro{\Shift}{8cm}% Should compute this based on num of items in #2  
        \begin{scope}[xshift=\Shift]
            \DNASequence[#1]{#4} 
        \end{scope}
    \end{scope}
    \pgfmathsetlength{\YShift}{\YShift\YShiftBetweenRows}%
}

\newcommand*{\ConnectNodes}[3][]{%
    % #1 = draw options
    % #2 = ending node
    % #3 = list of starting nodes
    \def\ListOfEndNodes{#3}
    \foreach \EndNode in \ListOfEndNodes {%
    \draw[red, <->, thick, #1] (#2) to[#1] (\EndNode);
    }%
}

\newcommand*{\Fit}[3][]{\node [inner sep=2pt, #1, fit= #3] (#2) {};}%

\begin{document}
\begin{tikzpicture}

    \ThreeDNASequences[Top]
        {C/blue!20,, A/cyan!30,,, G/blue!20,, G/cyan!30,, C/cyan!30}
        {C/blue!20, G/blue!20}
        {A/cyan!30, G/cyan!30, C/cyan!30};

    \ThreeDNASequences
        {A/green!20,, C/orange!50,,, C/green!20,, A/orange!50,, A/orange!50}
        {A/green!20, C/green!20}
        {C/orange!50, A/orange!50, A/orange!50};

    \ThreeDNASequences[Bottom]
        {C/blue!20,, A/cyan!30,,, G/blue!20,, G/cyan!30,, C/cyan!30}
        {C/blue!20, G/blue!20}
        {A/cyan!30, G/cyan!30, C/cyan!30};

%    % Now, draw the arrows as desired
%
%   \ConnectNodes[red, out=100, in=80, ]
%       {Top-12.north}
%       {Top-2.north,Top-7.north,Top-9.north};
%
%   \ConnectNodes[blue, out=-80, in=-100]
%       {Bottom-10.south east}
%       {Bottom-2.south,Bottom-7.south,Bottom-9.south};


   % Bottom connections
    \Fit[Fit Line Style 1, Fill Style 1]{LeftB1}{(Top-0.north west) (Bottom-0.south east)}
    \Fit[Fit Line Style 1, Fill Style 1]{LeftB2}{(Top-5.north west) (Bottom-5.south east)}
    \Fit[Fit Line Style 1, Fill Style 1]{RightB1}{(Top-10.north west) (Bottom-11.south east)}


    \ConnectNodes[Fit Line Style 1, solid, <-, out=-120, in=-20]
        {RightB1.south}
        {LeftB1.south, LeftB2.south};

%   % Top connections
%   \Fit[Fit Line Style 2, Fill Style 2]{LeftT1}{(Top-2.north west) (Bottom-2.south east)}
%   \Fit[Fit Line Style 2, Fill Style 2]{LeftT2}{(Top-7.north west) (Bottom-7.south east)}
%   \Fit[Fit Line Style 2, Fill Style 2]{LeftT3}{(Top-9.north west) (Bottom-9.south east)}
%   \Fit[Fit Line Style 2, Fill Style 2]{RightT1}{(Top-12.north west) (Bottom-14.south east)}
%
%
%   \ConnectNodes[Fit Line Style 2, solid, out=100, in=80, <-]
%       {RightT1.north}
%       {LeftT1.north, LeftT2.north, LeftT3.north};
\end{tikzpicture}
\end{document}

相关内容