创建复杂图表

创建复杂图表

我需要一些帮助来设计一种用于更多情况的方法。我在 tex.stackexchange.com 上搜索过解决方案,但到目前为止还没有看到对我有很大帮助的例子。

在撰写我的音乐学论文时,我需要创建分析图表,或者说网络:见下图。我见过用 LaTeX 制作的此类图表,但从未见过不涉及太多行代码的图表,除了出版之外,在任何层面上都无法实用 - 更不用说编码学位了。到目前为止,我一直在使用 Apple 的 Keynote 来实现这一点,而且大多数时候都很好,尤其是它处理将线连接到对象(如圆圈、添加箭头和操纵线)的方式。

但创建大于五边形的网络并非易事;六边形及以上的所有网络都必须手动从圆形开始创建,然后根据所需角的数量将其分成“块”,然后连接线条,删除“块”,最后连接圆形。更糟糕的是,导出图像非常麻烦:为了保持井然有序,我需要为每个音乐示例创建一个 Keynote 文件,因此它包含多个图表。我发现导出此文件的最佳方法是截取相关图表的屏幕截图 (!),然后将其添加到我的 tex 文件夹中。无论我做什么,结果都不可能 100% 完美,你可以想象我的强迫症有点刺痛……

我的理由是:如果我无论如何都要花很多时间手动创建它,为什么不做一个 TeX 解决方案呢?我很可能要读博士学位,需要这个工具来做很多事情,我认为它对其他音乐学家来说会是一个很好的工具。

从最基本的东西开始:是否有一些软件包已经提供了构建八声音阶网络所需的功能(如下图所示)?

对于语言应该是什么样子才能使其成为一种有效的工具,我有很多想法,但乞丐不能挑三拣四,所以我会先等着看你们说什么。

例子

答案1

您可以尝试 Tikz。通过指定角度和距离,可以很容易地正确定位元素。代码显示了屏幕截图的直接实现。

在此处输入图片描述

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc,arrows,backgrounds}

\begin{document}
% Style definition for the large circles. The minimum width sets the minimum diameter of the circles
\tikzstyle{t1}=[circle,draw=gray,line width=2pt,fill=white,minimum width=1.2cm]
% Style definition for the small circles. Similar to the large ones, but they have a dashed border and a smaller font.
\tikzstyle{t2}=[dashed,circle,draw=gray,line width=2pt,fill=white,minimum width=.6cm,font=\small\sffamily]

\begin{tikzpicture}[font=\sffamily]
    % The node in the center positioned at (0,0) with the name center and the label '$\mathsf{O_1}$'. 
    \node[font=\Huge\sffamily] at (0,0) (center) {$\mathsf{O_1}$};
    % First node in the ring with the style 't1'. It is positioned relative to the node 'center' with a distance of 3cm and an angle  of 0°. 
    \node[t1] at ($(center) + (0:3cm) $) (F) {$\mathsf{F}$};
    \node[t1] at ($(center) + (45:3cm) $) (Dm) {$\mathsf{Dm}$};
    \node[t1] at ($(center) + (90:3cm) $) (D) {$\mathsf{D}$};
    \node[t1] at ($(center) + (135:3cm) $) (Bm) {$\mathsf{Bm}$};
    \node[t1] at ($(center) + (180:3cm) $) (B) {$\mathsf{B}$};
    \node[t1] at ($(center) + (225:3cm) $) (Abm) {$\mathsf{A^bm}$};
    \node[t1] at ($(center) + (270:3cm) $) (Ab) {$\mathsf{A^b}$};
    \node[t1] at ($(center) + (315:3cm) $) (Fm) {$\mathsf{Fm}$};
    \node[t1] at ($(Ab) + (0,-2.5cm) $) (G) {$\mathsf{G}$};
    \node[t1,minimum width=0] at ($(G) + (2,.25cm) $) (Ebm) {$\mathsf{E^bm}$};

    % The connections between the nodes in the ring.
    \draw[line width=2pt,black] (D) -- (Dm) -- (F) -- (Fm) -- (Ab) -- (Abm) -- (B) -- (Bm) -- (D);
    % The arrow from 'D' to 'B'. '-triangle 45' sets the arrow tip to a triangle with an angle of 45°. 'to[bend left]' says, that the arrow should bend left. 
    \draw[line width=2pt,-triangle 45] (D) to[bend left] (B);
    % This one is a double headed arrow, so 'triangle 45-triangle 45' 
    \draw[line width=2pt,triangle 45-triangle 45] (B) to[bend left] (Ab);
    \draw[line width=2pt,triangle 45-triangle 45] (D) to[bend left] (Ab);
    \draw[line width=2pt,triangle 45-triangle 45] (Ab) to (G);
    % The arrow from 'Ab' to 'Ebm'. It's dashed, double headed and smaler than the other ones. 
    % 'to[out=290,in=150]' sets the angles at the startpoints of the arrow. I used this, because 'bend left' didn't fit. 
    % The node command is used add a label to the arrow. 'xshift' moves the label by 4pt to the right. 
    \draw[dashed,line width=1pt,triangle 45-triangle 45] (Ab) to[out=290,in=150] node[above,font=\bf\sffamily,xshift=4pt] {M} (Ebm);

    % The '/G' nodes on top. They are defined here, because they sould be on top of everything. You could also use layers but that's not necessary
    \node[t2] at ($(D) + (0cm,.7cm)$) (G1) {/G};
    \node[t2] at ($(B) + (0cm,.7cm)$) (G2) {/G};
    \node[t2] at ($(Ab) + (.7cm,0cm)$) (G3) {/G};


\end{tikzpicture}
\end{document}

答案2

您不需要绘制和放置每个节点,而是可以使用 Tikz 树来构建八边形,并按顺时针(或者如果您愿意,也可以逆时针)的方式绘制子节点。

然后设置每个子节点的角度(360 degrees / 8 children = 45 degrees在本例中)以及与父节点的距离。其他节点单独构建。

我唯一无法修复的就是字体粗细看起来太粗了。

输出

图1

代码

\documentclass[tikz,margin=10pt]{standalone}
\usepackage{fixltx2e} % needed for \subscript{}

\usetikzlibrary{shapes, trees, arrows.meta, calc,positioning,backgrounds}

\tikzset{
    every node/.style={circle, fill=white, line width=1.5pt, draw=gray, minimum size=1.2cm},
    small/.style={dashed, minimum size=5mm},
    alpath/.style={rectangle,draw=none, minimum size=5mm,fill=none},
    couple/.style args={[#1]#2}{
        label={[circle, fill=white, line width=1.5pt, draw=gray, dashed, minimum size=5mm,label distance=-10pt,#1]#2}},
    level 1/.style={sibling angle=45, level distance=2.5cm},
    edge from parent/.style= {draw=none},
}

\begin{document}
\begin{tikzpicture}[<->,{Latex}-{Latex}]\sffamily

    \node[draw=none,font=\Huge] (main) at (0,0) {O\textsubscript{1}} [clockwise from=90]
        child { node[couple={[small]90:/G}] (1) {D}}
        child { node (2) {Dm}}
        child { node (3) {F}}
        child { node (4) {Fm}}
        child { node[couple={[small]0:/G}] (5) {A\textsuperscript{b}}}
        child { node (6) {A\textsuperscript{b}m}}
        child { node[couple={[small]90:/G}] (7) {B}}
        child { node (8) {Bm}}
    ;
    \node[below =1cm of 5] (9) {G};
    \node[right =1cm of 9] (10) {E\textsuperscript{b}m};

% Edges
\begin{scope}[on background layer]
    \draw[ultra thick,-] (1) -- (2) -- (3) -- (4) -- (5) -- (6) -- (7) -- (8) -- (1);
\end{scope}

    \draw[ultra thick,{Latex}-{Latex}] (1) edge[bend left] (5);
    \draw[ultra thick,{Latex}-{Latex}] (5) edge[bend right] (7);
    \draw[ultra thick,{Latex}-{Latex}] (7) edge[bend right] (1);
    \draw[ultra thick] (5) -- (9);
    \draw[-,dashed,thick] (10.north west) edge[bend left=10,<->,{Latex}-{Latex}] node[alpath,midway,anchor=west] {M} (5.south east) ;
\end{tikzpicture}
\end{document}

答案3

使用以下软件包的解决方案pst-poly

\documentclass[pdf, x11names]{standalone}%

\usepackage [default]{cabin}
\usepackage{changes}
\usepackage{pst-poly}

\newcommand\circleG{\circlenode[ linecolor=SlateGray4!50!, fillstyle=solid, fillcolor=white, ]{}{/G}}

\begin{document}

\psset{unit=2.8cm, radius=16pt, linecolor=SlateGray4!50!, linewidth=1.5pt, framesep=4pt, arrowinset=0, arrowscale=1.5}
\fbox{\begin{pspicture*}(-2,-2)(2,3)
  \providecommand{\PstPolygonNode}{%
    \Cnode[linecolor=SlateGray4!50!, fillstyle=solid, fillcolor=white](1;\INode ){N}
  }
  \rput{22.5}(0,0) {\PstOctogon[PolyName=A, linecolor=black]}
  \rput(A1){Dm}\rput(A2){D}\rput(A3){Bm}\rput(A4){B}\rput(A5){A\boldmath$^{^{\scriptstyle\flat}}\mkern-7mu$m}\rput(A6){A\rlap{\boldmath$^\flat$}} \rput(A7){Fm}\rput(A8){F}
  \nput[labelsep=45pt]{-90}{A6}{\circlenode[framesep=9.6pt]{G}{G}}
  \nput[labelsep=28pt]{0}{G}{\circlenode[framesep=2pt]{B}{B\boldmath$^{^{\scriptstyle\flat}}\mkern-7mu$m}}
  \psset{labelsep=8pt, linestyle=dashed, dash=3pt 4pt}
  \nput{90}{A2}{\circleG}\nput{180}{A4}{\circleG}\nput{0}{A6}{\circleG}
  \rput(A0){\LARGE O\textsubscript{1}}
  %%%Node connections
  \psset{arrows= <->, linestyle=solid, linecolor=black, nodesep=16pt, arcangle=30}
  \ncarc{A2}{A6}\ncarc[arrows=->]{A2}{A4}\ncarc{A4}{A6}
  \ncline[nodesepB=0pt]{A6}{G}\ncarc[linewidth=1pt, linestyle=dashed, arcangle=10, nodesepA=0pt]{B}{A6}\nbput[labelsep=2pt]{M}
  \end{pspicture*}}

\end{document} %

在此处输入图片描述

答案4

这是另一个 TiZ 解决方案。它使用库regular polygon中的选项shapes.geometric。库positioning用于其他节点的相对位置。

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{positioning}

\tikzstyle{circles}  = [circle,draw=gray,line width=2pt,minimum width=1.2cm]
\tikzstyle{dcircles} = [circle,draw=gray,line width=2pt,minimum width=0.6cm,fill=white,dashed]

\begin{document}
    \begin{tikzpicture}[font=\sffamily,>=latex]
        % Polygon
        \node[regular polygon, regular polygon sides=8, minimum width=6cm, rotate=22.5] (O) {}  (O.center) node[font=\Huge\sffamily] (cntr) {O$_\mathsf{1}$};

        % Polygon vertices
        \foreach \n/\c [count=\i] in {D/D,Bm/Bm,B/B,Abm/A$^\mathsf{b}$m,Ab/A$^\mathsf{b}$,Fm/Fm,F/F,Dm/Dm}
            \node[circles] at (O.corner \i)  (\n) {\c};
        % Other vertices
        \node[circles,below=1cm of Ab] (G) {G};     
        \node[circles,above right=-.6cm and 1cm of G] (Ebm) {E$^\mathsf{b}$m};

        % Connect polygon vertices
        \draw[line width=2pt,black] (D) -- (Dm) -- (F) -- (Fm) -- (Ab) -- (Abm) -- (B) -- (Bm) -- (D);
        % Draw arrows
        \foreach \f/\t/\l/\b in {D/B/->/bend left, B/Ab/<->/bend left, D/Ab/<->/bend left, Ab/G/<->/}
            \draw[line width=2pt,\l] (\f) to[\b] (\t);
        \draw[dashed,line width=1pt,<->] (Ab) to[out=290,in=150] node[above,xshift=4pt] {M} (Ebm);

        % Add remaining vertices
        \foreach \n/\d in {D/above, B/above, Ab/right}
            \node[dcircles,\d=-.35cm of \n] {/G};
    \end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容