네트워크 플롯을 그리고 싶은데 많은 모서리가 겹쳐져 있습니다. 오버레이된 가장자리를 볼 수 있도록 가장자리의 곡률을 변경하고 싶습니다.
나의 초기 아이디어는 곡률을 20-30도 사이에서 무작위로 균일하게 만드는 것이었습니다. 하지만 TikZ에서 쉽게 구현할 수 있는지는 모르겠습니다.
이 솔루션은 곡률을 수동으로 지정하지 않고도 작동하므로 더 큰 네트워크에도 적용할 수 있습니다.
MWE 코드:
\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}
편집하다: 맥락을 제공하기 위해 목표는 다음에서 영감을 받은(그러나 그보다 작은) 것을 그리는 것입니다.
(원천:http://blog.revolutionanalytics.com/2010/12/facebooks-social-network-graph.html)
답변1
다음은 무차별 대입 방법입니다.
\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}
정말로 임의성을 추가하고 싶다면 이것은 쉽습니다.
답변2
노드 이름이 항상 정수인 경우 에지의 마지막 대상과 소스가 현재 항목과 동일한지 확인하고 동일한 경우 값을 늘리는 이 접근 방식을 사용할 수 있습니다 bend right
.
단점: 이는 동일한 노드의 가장자리가 서로 옆에 배치되는 경우에만 작동합니다. 그러면 1/2, 3/2, 1/2
다시 가장자리가 겹쳐지게 됩니다.
\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}
편집하다:다음에서 가져온 정렬 메커니즘을 추가했습니다.여기(어쩌면 그러한 목록을 정렬하는 것이 더 쉬울 수도 있습니다):
\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}
답변3
이것은 내 자신의 솔루션입니다(MWE에서는 약간 보기 흉하지만 일단 네트워크가 실제로 밀도가 높아지면 상당히 좋을 수 있습니다).
\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}