有没有办法使用 TeX 本身(最好使用 TikZ)来生成这些图形?如果是,那么我还想在节点旁边添加标签,而不是使用图例。
这是我正在阅读的一篇论文的截图,我更喜欢使用 TeX 来创建它们,而不是使用一些外部工具。
编辑
我读了答案这里但我想在线上添加“十字”,而不是指向十字必须存在的位置的灰色线。此外,我不知道如何将十字更改为上面绘制的图表中给出的不同符号。
答案1
您可以使用to
角度作为线进入和离开节点的参数。
\draw (from-node) to[out=angle at from-node,in=angle at to-node] (to-node);
这些角度是从 x 轴正方向测量的。
\documentclass[border=1mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes}
\begin{document}
\tikzset
{dest/.style={circle,draw,minimum width=1mm,inner sep=0mm},
start/.style={diamond,fill,draw,minimum width=1mm, minimum height=1mm,inner sep=0mm},
terminal/.style={circle,draw,minimum width=1.5mm,inner sep=0mm,label={[label distance=-2.75mm]{\tiny+}}}
}
\begin{tikzpicture}
\node[start,label={[right]:$s$}] (s) at (0,0) {};
\node[dest,label={[left]:$d_1$}] (d1) at (-1,0.5) {};
\node[dest,label={[right]:$d_2$}] (d2) at (0.3,0.6) {};
\node[dest,label={[right]:$d_3$}] (d3) at (0,1.5) {};
\node[dest,label=$d_4$] (d4) at (-1,2) {};
\node[terminal,label={[left]:$t$}] (t) at (-0.9,1.3) {};
\draw (s) to[out=170,in=-90] (d1);
\draw (d1) to[out=70,in=-100] (d2);
\draw (d2) to[out=100,in=-60] (d3);
\draw (d3) to[out=120,in=30] (d4);
\draw (d4) to[out=-110,in=100] (t);
\end{tikzpicture}
\end{document}
答案2
为了实现更加自动化的平滑连接,减少人工劳动,您可以使用\draw [smooth] plot coordinates {(0,0) (1,0) (1,0) (1,1)};
键tension=1.5
指定直线的紧密度。参见这个答案有关此类命令的功能的更多详细讨论。
使用expl3
(我加载了xparse
并使用\NewDocumentCommand
而不是\newcommand
但该部分可以用 LaTeX2e 完成)我定义了一个新命令,该命令将一组坐标以;
(这可以是任何合理的分隔符,我使用;
over,
因为坐标自然有(a,b)
描述)分隔作为单个输入。然后将坐标拆分成一个seq
变量( ),从中提取它们进行绘图。以及一个可选参数,用于设置绘图的\l__banachtarski_coords_seq
值。tension
据我所知TikZ
选项中不提供mark first
、mark last
和mark middle
类型命令\draw plot
,因此我首先在所有点之间绘制一条平滑的线,然后使用一种相当低效的方法放置标记,即在第一个坐标处放置一个标记,在第二个坐标处放置一个标记,使用不同的标记,在此过程中将\draw plot [smooth, tension=1.5] coordinates { \seq_use:Nn \l__banachtarski_coords_seq { ~ } };
它们从\l__banachtarski_coords_seq
\seq_pop_left:NN \l__banachtarski_coords_seq \l__banachtarski_temp_tl
\draw plot [only~marks,mark=diamond*,mark~options={fill=black}] coordinates {
\l__banachtarski_temp_tl
};
\seq_pop_right:NN \l__banachtarski_coords_seq \l__banachtarski_temp_tl
\draw plot [only~marks,mark=oplus*,mark~options={fill=gray}] coordinates {
\l__banachtarski_temp_tl
};
然后用第三个标记绘制剩余的中间坐标
\draw plot [only~marks,mark=*,mark~options={fill=gray}] coordinates {
\seq_use:Nn \l__banachtarski_coords_seq { ~ }
};
only~marks
(只画标记,不画连接线)必须使用,而不是only marks
因为这一切都发生在内部\ExplSyntaxOn ... \ExplSyntaxOff
尽管它可能仅需要用于绘制最终的一组标记。
因此(使用与gernot 的回答它可以以更大的努力提供更精细的控制)可以生成 从
\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{plotmarks}
\ExplSyntaxOn
\seq_new:N \l__banachtarski_coords_seq
\tl_new:N \l__banachtarski_temp_tl
\NewDocumentCommand \smoothgraph { O{1} m }
{
\seq_set_split:Nnn \l__banachtarski_coords_seq { ; } { #2 }
\draw plot [smooth, tension=#1] coordinates { \seq_use:Nn \l__banachtarski_coords_seq { ~ } };
\seq_pop_left:NN \l__banachtarski_coords_seq \l__banachtarski_temp_tl
\draw plot [only~marks,mark=diamond*,mark~options={fill=black}] coordinates { \l__banachtarski_temp_tl };
\seq_pop_right:NN \l__banachtarski_coords_seq \l__banachtarski_temp_tl
\draw plot [only~marks,mark=oplus*,mark~options={fill=gray}] coordinates { \l__banachtarski_temp_tl };
\draw plot [only~marks,mark=*,mark~options={fill=gray}] coordinates { \seq_use:Nn \l__banachtarski_coords_seq { ~ } };
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
\smoothgraph{(0,0);(-1,0.5);(0.3,0.6);(0,1.5);(-1,2);(-0.9,1.3)}
\end{tikzpicture}
\begin{tikzpicture}
\smoothgraph[2]{(0,0);(-1,0.5);(0.3,0.6);(0,1.5);(-1,2);(-0.9,1.3)}
\end{tikzpicture}
\end{document}