Zeichnen Sie Kanten mit unterschiedlicher/zufälliger Krümmung in TikZ

Zeichnen Sie Kanten mit unterschiedlicher/zufälliger Krümmung in TikZ

Ich möchte ein Netzwerkdiagramm zeichnen, aber viele Kanten überlagern sich. Ich möchte die Krümmung der Kanten variieren, um überlagernde Kanten sichtbar zu machen.

Meine ursprüngliche Idee war, die Krümmung zufällig und gleichmäßig zwischen 20 und 30 Grad zu gestalten. Aber ich weiß nicht, ob sich das in TikZ so einfach umsetzen lässt.

Die Lösung soll ohne manuelle Vorgabe der Krümmungen funktionieren, um auch auf größere Netzwerke anwendbar zu sein.

Das Ergebnis sollte ungefähr so ​​aussehen: Netzwerkdiagramm mit mehreren Kanten

MWE-Code:

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\node at (0,0) [circle, fill=blue] (1) {};
\node at (0,10) [circle, fill=blue] (2) {};
\node at (7,10) [circle, fill=blue] (3) {};
\node at (10,4) [circle, fill=blue] (4) {};
\node at (4,3) [circle, fill=blue] (5) {};
\draw (1) to[bend right] (2);
\draw (1) to[bend right] (2);
\draw (1) to[bend right] (2);
\draw (2) to[bend right] (1);
\draw (1) to[bend right] (4);
\draw (2) to[bend right] (3);
\draw (2) to[bend right] (3);
\draw (2) to[bend right] (3);
\draw (2) to[bend right] (5);
\draw (3) to[bend right] (2);
\draw (3) to[bend right] (5);
\draw (3) to[bend right] (5);
\draw (3) to[bend right] (5);
\draw (3) to[bend right] (4);
\draw (4) to[bend right] (1);
\draw (4) to[bend right] (1);
\draw (4) to[bend right] (3);
\draw (4) to[bend right] (3);
\end{tikzpicture}
\end{document}

bearbeiten: Um einen Kontext zu geben, besteht das Ziel darin, etwas zu zeichnen, das hiervon inspiriert ist (aber kleiner ist):

Facebook-Netzwerk (Quelle:http://blog.revolutionanalytics.com/2010/12/facebooks-social-network-graph.html)

Antwort1

Hier ist eine Brute-Force-Methode.

\documentclass{article}
\usepackage{tikz}
\newcommand{\MultiConnect}[5][]{%
\pgfmathsetmacro{\imin}{#2-5*#3}
\pgfmathsetmacro{\imax}{#2+5*#3}
\pgfmathsetmacro{\inext}{#2-5*#3+10}
\foreach \i in {\imin,\inext,...,\imax}
\draw[#1] (#4) to[bend right=\i] (#5);
}
\begin{document}
The command 
\verb|\MultiConnect{offset}{# of connections}{first node}{second node}| 
allows you to draw connections.

\begin{tikzpicture}
\node at (0,0) [circle, fill=blue] (1) {};
\node at (0,10) [circle, fill=blue] (2) {};
\node at (7,10) [circle, fill=blue] (3) {};
\node at (10,4) [circle, fill=blue] (4) {};
\node at (4,3) [circle, fill=blue] (5) {};
\foreach \j in {1,...,4}{\pgfmathtruncatemacro{\nextj}{\j+1}
\foreach \k in {\nextj,...,5}
{
\MultiConnect{0}{4}{\j}{\k}
}
}
\end{tikzpicture}

\begin{tikzpicture}
\node at (0,0) [circle, fill=blue] (1) {};
\node at (0,10) [circle, fill=blue] (2) {};
\node at (7,10) [circle, fill=blue] (3) {};
\node at (10,4) [circle, fill=blue] (4) {};
\node at (4,3) [circle, fill=blue] (5) {};
\foreach \j in {1,...,4}{\pgfmathtruncatemacro{\nextj}{\j+1}
\foreach \k in {\nextj,...,5}
{
\pgfmathsetmacro{\Offset}{20+10*rand}
\typeout{\j,\k,\Offset}
\MultiConnect{\Offset}{4}{\j}{\k}
}
}
\end{tikzpicture}

\end{document}

Bildbeschreibung hier eingeben

Wenn Sie wirklich etwas Zufälligkeit einfügen möchten, ist dies einfach.

Bildbeschreibung hier eingeben

Antwort2

Wenn Ihre Knotennamen immer ganze Zahlen sind, können Sie diesen Ansatz verwenden, der überprüft, ob das letzte Ziel und die letzte Quelle der Kante mit den aktuellen übereinstimmen, und wenn ja, den bend rightWert erhöht:

Nachteil: Dies funktioniert nur, wenn Kanten von und zu denselben Knoten nebeneinander gelegt werden. Das 1/2, 3/2, 1/2würde wiederum zu einer Überlagerung der Kanten führen.

\documentclass[tikz]{standalone}

\newcounter{lastsource}
\newcounter{lasttarget}
\newcounter{samesourcetarget}

\begin{document}
\begin{tikzpicture}
\node at (0,0)  [circle, fill=blue] (1) {};
\node at (0,10) [circle, fill=blue] (2) {};
\node at (7,10) [circle, fill=blue] (3) {};
\node at (10,4) [circle, fill=blue] (4) {};
\node at (4,3)  [circle, fill=blue] (5) {};

\def\defaultbend{30}
\def\increasebend{5}

\setcounter{samesourcetarget}{\defaultbend}
\foreach \source/\target in {1/2, 1/2, 1/2, 2/1, 1/4, 2/3, 2/3, 2/2, 2/5, 3/2, 3/5, 3/5, 3/5, 3/4, 4/1, 4/1, 4/3, 4/3}{
 \ifnum\value{lastsource}=\source 
  \ifnum\value{lasttarget}=\target
   \addtocounter{samesourcetarget}{\increasebend}
  \else
   \setcounter{samesourcetarget}{\defaultbend}
  \fi
 \else
  \setcounter{samesourcetarget}{\defaultbend}
 \fi
 \draw (\source) to[bend right=\thesamesourcetarget] (\target);
 \setcounter{lastsource}{\source}
 \setcounter{lasttarget}{\target}
}

\end{tikzpicture}
\end{document}

Bildbeschreibung hier eingeben


Bearbeiten:Hinzugefügt wurde ein Sortiermechanismus ausHier(vielleicht ist es einfacher, eine solche Liste zu sortieren):

\documentclass[tikz]{standalone}
\usepackage{expl3,l3sort,xparse}

\ExplSyntaxOn
\prg_new_conditional:Nnn \sort_string_if_before:nn{ p,T,F,TF }{
 \int_compare:nTF {\pdftex_strcmp:D{#1}{#2} < 0}{\prg_return_true:}{\prg_return_false:}
}

\NewDocumentCommand{\sortlist}{smm}{
 \IfBooleanTF{#1}{
  \clist_set:No \l__sort_sortlist_data_clist{#2}
 }{
  \clist_set:Nn \l__sort_sortlist_data_clist{#2}
 }
 \sort_sortlist:N \l__sort_sortlist_data_clist
 \clist_set_eq:NN #3 \l__sort_sortlist_data_clist
}
\clist_new:N \l__sort_sortlist_data_clist

\cs_new_protected:Nn \sort_sortlist:N{
 \clist_sort:Nn #1{
  \sort_string_if_before:nnTF{##1}{##2}{\sort_ordered:}{\sort_reversed:}
  }
}
\ExplSyntaxOff

\newcounter{lastsource}
\newcounter{lasttarget}
\newcounter{samesourcetarget}

\begin{document}

\begin{tikzpicture}
\node at (0,0)  [circle, fill=blue] (1) {};
\node at (0,10) [circle, fill=blue] (2) {};
\node at (7,10) [circle, fill=blue] (3) {};
\node at (10,4) [circle, fill=blue] (4) {};
\node at (4,3)  [circle, fill=blue] (5) {};

\def\defaultbend{30}
\def\increasebend{5}

\sortlist{2/5, 3/2, 3/5, 1/2, 4/1, 4/3, 1/2, 2/1, 1/4, 2/3, 2/3, 2/2, 3/5, 1/2, 3/5, 3/4, 4/1, 4/3}{\sortedcoords}

\setcounter{samesourcetarget}{\defaultbend}
\foreach \source/\target in \sortedcoords {
 \ifnum\value{lastsource}=\source 
  \ifnum\value{lasttarget}=\target
   \addtocounter{samesourcetarget}{\increasebend}
  \else
   \setcounter{samesourcetarget}{\defaultbend}
  \fi
 \else
  \setcounter{samesourcetarget}{\defaultbend}
 \fi
 \draw (\source) to[bend right=\thesamesourcetarget] (\target);
 \setcounter{lastsource}{\source}
 \setcounter{lasttarget}{\target}
}

\end{tikzpicture}
\end{document}

Antwort3

Dies ist meine eigene Lösung (im MWE ist sie ein wenig hässlich, aber wenn das Netzwerk erst einmal richtig dicht ist, kann sie ganz nett sein):

\documentclass[tikz]{standalone}
\newcommand{\drawrcurvededge}[2]{
\pgfmathsetmacro{\Offset}{20+10*rand}
\draw (#1) to[bend right=\Offset] (#2);
}
\begin{document}
\begin{tikzpicture}
\node at (0,0) [circle, fill=blue] (1) {};
\node at (0,10) [circle, fill=blue] (2) {};
\node at (7,10) [circle, fill=blue] (3) {};
\node at (10,4) [circle, fill=blue] (4) {};
\node at (4,3) [circle, fill=blue] (5) {};
\drawrcurvededge{1}{2}
\drawrcurvededge{1}{2}
\drawrcurvededge{1}{2}
\drawrcurvededge{2}{1}
\drawrcurvededge{1}{4}
\drawrcurvededge{2}{3}
\drawrcurvededge{2}{3}
\drawrcurvededge{2}{3}
\drawrcurvededge{2}{5}
\drawrcurvededge{3}{2}
\drawrcurvededge{3}{5}
\drawrcurvededge{3}{5}
\drawrcurvededge{3}{5}
\drawrcurvededge{3}{4}
\drawrcurvededge{4}{1}
\drawrcurvededge{4}{1}
\drawrcurvededge{4}{3}
\drawrcurvededge{4}{3}
\end{tikzpicture}
\end{document}

Bildbeschreibung hier eingeben

verwandte Informationen