Notas:

Notas:

Eu tenho o seguinte trecho de código TikZ e queria saber se ele pode ser otimizado. (Na verdade, tenho certeza de que pode ser!)

O principal problema é este: quando giro o primeiro lote de nós cercados pela elipse para criar o segundo lote, a elipse fica fora do lugar. (Não está onde eu esperava. Não tenho certeza de qual ponto está fixo na rotação.) Tenho que ajustá-lo às cegas para movê-lo para o local desejado.

O mesmo vale para os rótulos “Comunidade 2” e “Comunidade 3”. As coordenadas giradas não parecem corresponder ao que eu esperava e tenho que ajustá-las cegamente com sucesso limitado.

Em uma observação não relacionada: também experimentei loops for, mas como quero que as bordas de cada comunidade sejam um pouco diferentes, parece que copiar e colar direto é mais fácil?

Outras otimizações também são bem-vindas.

código

\documentclass[tikz]{standalone}

\begin{document}
\begin{tikzpicture}[scale = 1,node distance = 10mm]

\tikzset{
  every node/.append style={circle, thick,
    inner sep=0pt, minimum size = 3mm},
  every label/.append style={red},
  c1/.style={draw=blue!50,fill=blue!20},
  c2/.style={draw=green!80,fill=green!40},
  c3/.style={draw=red!80,fill=red!40}
}   

\filldraw[rotate=30,blue!10] (0.8,0.1) ellipse (30pt and 25pt);
\node at (1,1.7) {Community 1};
\node[c1] (1) at (0,0) {};
\node[c1] (2) at (1,1)  {}
edge (1);
\node[c1] (3) at (0.7,0.2) {}
edge (2)
edge (1);
\node[c1] (4) at (0.2,0.7) {}
edge (3)
edge (2);
\node[c1] (5) at (1.3,0.5) {}
edge (2)
edge (4);

\begin{scope}[yshift=-2cm,rotate around={-40:(0,0)}]
\filldraw[rotate=30,green!10] (0.8,0.1) ellipse (30pt and 25pt);
\node at (1.2,-0.2) {Community 2};
\node[c2] (A) at (0,0) {};
\node[c2] (B) at (1,1)  {}
edge (A);
\node[c2] (C) at (0.7,0.2) {}
edge (B)
edge (A);
\node[c2] (D) at (0.2,0.7) {}
edge (C)
edge (B);
\node[c2] (E) at (1.3,0.5) {}
edge (C)
edge (D);
\end{scope}

\begin{scope}[xshift=2cm,yshift=-0.5cm,rotate around={-40:(0,0)}]
\filldraw[rotate=30,red!10] (0.8,0.1) ellipse (30pt and 25pt);   
\node[c3] (a) at (0,0) {};
\node[c3] (b) at (1,1)  {}
edge (a);
\node[c3] (c) at (0.7,0.2) {}
edge (b)
edge (a);
\node[c3] (d) at (0.2,0.7) {}
edge (a)
edge (b);
\node[c3] (e) at (1.3,0.5) {}
edge (c)
edge (d);
\node[above of=b] {Community 3};
\end{scope}

\draw (3) -- (A);
\draw (4) -- (D);
\draw (5) -- (a);
\draw (c) -- (E);
\draw (e) -- (B);

\end{tikzpicture}
\end{document}

Saída

insira a descrição da imagem aqui

Responder1

Você deve definir uma macro para o desenho para poder reutilizá-lo:

insira a descrição da imagem aqui

Notas:

  • Como não sei a intenção do desenho e com que cuidado você deseja escolher o posicionamento e a conectividade, baseei-o no código fornecido.
  • Uma coisa a ter em mente ao fazer coisas repetidas é que cada tarefa deve ser pensada de maneira semelhante. Por exemplo, ao posicionar o texto do nó, você usa coordenadas absolutas duas vezes e, na terceira vez, usa um posicionamento relativo. Decidi escolher a posição absoluta, mas isso pode não ser o ideal. É claro que isso tornou a colocação do rótulo do terceiro nó uma espécie de suposição por tentativa e erro. Veja Relative Placement of Labelsa seção abaixo que pode ser uma opção melhor.
  • Os nós são rotulados como A<color>, ... D<color>(onde <color>é o terceiro parâmetro para \MyNodes) para que possam ser nomeados sistematicamente e depois referenciados conforme desejado fora do desenho dos nós.

Código: Colocação Fixa de Etiquetas

\documentclass[tikz, border=2pt]{standalone}

\begin{document}
\begin{tikzpicture}[scale = 1,node distance = 10mm]

\tikzset{
  every node/.append style={circle, thick,
    inner sep=0pt, minimum size = 3mm},
  every label/.append style={red},
  c1/.style={draw=blue!50,fill=blue!20},
  c2/.style={draw=green!80,fill=green!40},
  c3/.style={draw=red!80,fill=red!40}
} 

\newcommand*{\MyNodes}[6]{%
    % #1 = style
    % #2 = style
    % #3 = node name suffix.
    % #4 = node to connect to last node
    % #5 = label position
    % #6 = label text
    \filldraw[rotate=30,#1] (0.8,0.1) ellipse (30pt and 25pt);
    \node at #5 {#6};
    \node[#2] (A#3) at (0,0) {};
    \node[#2] (B#3) at (1,1)  {}
    edge (A#3);
    \node[#2] (C#3) at (0.7,0.2) {}
    edge (B#3)
    edge (A#3);
    \node[#2] (D#3) at (0.2,0.7) {}
    edge (C#3)
    edge (B#3);
    \node[#2] (E#3) at (1.3,0.5) {}
    edge (#4#3)
    edge (D#3);
}%  

\MyNodes{blue!10}{c1}{Blue}{B}{(1,1.7)}{Community 1}

\begin{scope}[yshift=-2cm,rotate around={-40:(0,0)}]
    \MyNodes{green!10}{c2}{Green}{C}{(1.2,-0.2)}{Community 2}
\end{scope}

\begin{scope}[xshift=2cm,yshift=-0.5cm,rotate around={-40:(0,0)}]
    \MyNodes{red!10}{c3}{Red}{C}{(0.5,1.75)}{Community 3}
\end{scope}

\draw (CBlue) -- (AGreen);
\draw (DBlue) -- (DGreen);
\draw (EBlue) -- (ARed);
\draw (CRed) -- (EGreen);
\draw (ERed) -- (BGreen);

\end{tikzpicture}
\end{document}

Você também pode colocar os rótulos dos nós de maneira relativa, o que considero uma opção melhor. Para determinar onde colocar os rótulos, é útil saber quais rótulos estão onde, e a \Debugmacro abaixo permite que você veja isso. Se você remover o comentário da linha subsequente no MWE, os rótulos dos nós serão suprimidos.

insira a descrição da imagem aqui

Código: Colocação Relativa de Etiquetas

\documentclass{article}
\usepackage{tikz}

\tikzset{%
  every node/.append style={circle, thick,
    inner sep=0pt, minimum size = 3mm},
  every label/.append style={red},
  c1/.style={draw=blue!50,fill=blue!20},
  c2/.style={draw=green!80,fill=green!40},
  c3/.style={draw=red!80,fill=red!40}
} 

\newcommand*{\Debug}[1]{\tiny#1}%
%\renewcommand*{\Debug}[1]{}% Comment this out for debugging

\newcommand*{\MyNodes}[6]{%
    % #1 = style
    % #2 = style
    % #3 = node name sufffix.
    % #4 = node to connect to last node
    % #5 = label position
    % #6 = label text
    \filldraw[rotate=30,#1] (0.8,0.1) ellipse (30pt and 25pt);
    \node[#2] (A#3) at (0,0) {\Debug{A}};
    \node[#2] (B#3) at (1,1)  {\Debug{B}}
    edge (A#3);
    \node[#2] (C#3) at (0.7,0.2) {\Debug{C}}
    edge (B#3)
    edge (A#3);
    \node[#2] (D#3) at (0.2,0.7) {\Debug{D}}
    edge (C#3)
    edge (B#3);
    \node[#2] (E#3) at (1.3,0.5) {\Debug{E}}
    edge (#4#3)
    edge (D#3);
    \node [#5#3] {#6};
}%  

\begin{document}
\begin{tikzpicture}[scale = 1,node distance = 10mm, thick]

\MyNodes{blue!10}{c1}{Blue}{B}{above of=D}{Community 1}

\begin{scope}[yshift=-2cm,rotate around={-40:(0,0)}]
    \MyNodes{green!10}{c2}{Green}{C}{below of=C}{Community 2} 
\end{scope}

\begin{scope}[xshift=2cm,yshift=-0.5cm,rotate around={-40:(0,0)}]
    \MyNodes{red!10}{c3}{Red}{C}{above of=B}{Community 3}
\end{scope}

\draw (CBlue) -- (AGreen);
\draw (DBlue) -- (DGreen);
\draw (EBlue) -- (ARed);
\draw (CRed)  -- (EGreen);
\draw (ERed)  -- (BGreen);

\end{tikzpicture}
\end{document}

Responder2

Outra tentativa de otimização. Isso usa chaves PGF.

Isenção de responsabilidade: o resultado não é exatamente o mesmo, pois usei o ellipsenó em vez do ellipsecaminho (e tive que ajustar um pouco as coordenadas).
A vantagem que vi aqui foi a utilização da labelopção de adicionar os rótulos “Comunidade”. Além disso, você pode consultá-lo para uso posterior.

Existe um comando:

\drawBlob[<optional arguments](<coordinate>);

É (<coordinate>)onde (0,0)está o sistema de coordenadas local.
Como são algumas transformações acontecendo na imagem, não tenho muita certeza de onde estão as bolhas. Observe apenas que, sem rotação, o primeiro mini blob ( A) estará em (<coordinate>).

Você pode usar os estilos

  • every blob picture,
  • every mini blob,
  • every blob, e
  • every mini blob edge

para personalizar o conteúdo. Existem configurações semelhantes ao every nodeestilo. Para cada every <something>estilo existe um <something>estilo que anexa seu elemento ao everyestilo correspondente.

Além disso, existem mais três chaves:

  • connect mini blobs,
  • blob name, e
  • rotate blob.

A rotate blobtecla gira a imagem inteira (a bolha grande e as mini bolhas) em torno do centro da bolha grande.

O valor da blob namechave será usado para nomear o blob grande (que recebe o nome da chave) e os mini blobs (que são nomeados <value of blob name>-<char>onde <char>está entre Ae E).

Se blob namenão for fornecido (por exemplo, vazio, se um padrão não for especificado), os nós receberão um nome interno (pelo qual ainda poderão ser referenciados posteriormente devido a um contador interno).
O contador não é realmente necessário quando os nós não serão referenciados posteriormente…

Finalmente, existe connect mini blobs. Essa chave deve receber uma lista de miniblobs que devem ser conectados dentro do blob.
Como seu exemplo parece sugerir que eles estão sempre conectados da mesma maneira, eu pré-defini esse estilo com

\tikzset{connect mini blobs={A/B,A/C,B/C,B/D,C/D,C/E,D/E}}

Isto traz à tona a vantagem de usar chaves PGF. Você pode definir valores padrão, alterá-los no meio do documento, definir .appendconfigurações e ter configurações diferentes para cada novo blob.

Você também pode definir mini blob <char>estilos para personalizar ainda mais cada mini blob.

E há every minin blob edge, para a linha das bordas desenhadas internamente entre as mini bolhas.

MelhoriasouTalvez a fitbiblioteca?

Observe como existem linhas semelhantes ao desenhar as mini bolhas?

Uma melhoria seria personalizar também o número e a localização desses mini blobs. Algumas chaves e um \foreachbastariam.

A elipse pode - com a ajuda da backgroundbiblioteca - ser desenhada com fit(por exemplo fit=(\qrr@blob@name-A)(\qrr@blob@name-B)…), embora a rotação desta elipse tenha que ser definida manualmente e o tamanho real dependa de rotate blob. Novamente, muitas transformações acontecendo.

Código

\documentclass[tikz]{standalone}
\usetikzlibrary{shapes.geometric}
\makeatletter
%% Setup
\tikzset{
    connect mini blobs/.store in=\qrr@blob@connections,
    connect mini blobs=,
    blob name/.store in=\qrr@blob@name,
    blob name=,
    rotate blob/.store in=\qrr@blob@rotate,
    rotate blob=0,
    % short-cut styles
    blob picture/.style={every blob picture/.append style={#1}},
    mini blob/.style={every mini blob/.append style={#1}},
    blob/.style={every blob/.append style={#1}},
    mini blob edge/.style={every mini blob edge/.append style=#1},
    % a few defaults
    every blob picture/.style={},
    every mini blob/.style={shape=circle, thick, draw, minimum size=3mm},
    every blob/.style={shape=ellipse, draw, fill, inner sep=0pt, minimum width=60pt, minimum height=50pt},
    every mini blob edge/.style={thick},
}

\newcount\c@qrr@blob@count
\newcommand*{\drawBlob}[1][]{\begingroup\tikzset{#1}\draw@blob}
\def\draw@blob(#1){%
    \ifx\qrr@blob@name\pgfutil@empty
        \edef\qrr@blob@name{qrr@mini-blob@\the\c@qrr@blob@count}%
    \fi
    \scope[absolute, every blob picture/.try]
        \node[shift={(#1)}, rotate=30+\qrr@blob@rotate, every blob/.try] (\qrr@blob@name) at (0.6,0.5) {};
        \node[every mini blob/.try, mini blob A/.try,  shift={(#1)}, ] (\qrr@blob@name-A) at ([rotate around={\qrr@blob@rotate:(0.6,0.5)}] 0,0)     {};
        \node[every mini blob/.try, mini blob B/.try,  shift={(#1)}, ] (\qrr@blob@name-B) at ([rotate around={\qrr@blob@rotate:(0.6,0.5)}] 1,1)     {};
        \node[every mini blob/.try, mini blob C/.try,  shift={(#1)}, ] (\qrr@blob@name-C) at ([rotate around={\qrr@blob@rotate:(0.6,0.5)}] 0.7,0.2) {};
        \node[every mini blob/.try, mini blob D/.try,  shift={(#1)}, ] (\qrr@blob@name-D) at ([rotate around={\qrr@blob@rotate:(0.6,0.5)}] 0.2,0.7) {};
        \node[every mini blob/.try, mini blob E/.try,  shift={(#1)}, ] (\qrr@blob@name-E) at ([rotate around={\qrr@blob@rotate:(0.6,0.5)}] 1.3,0.5) {};
        \foreach \qrr@blob@connection@start/\qrr@blob@connection@target in \qrr@blob@connections {
            \path[every mini blob edge/.try] (\qrr@blob@name-\qrr@blob@connection@start) edge (\qrr@blob@name-\qrr@blob@connection@target);}
    \endscope
    \endgroup
    \advance\c@qrr@blob@count\@ne
}
\makeatother

%%% Standard connections
\tikzset{connect mini blobs={A/B,A/C,B/C,B/D,C/D,C/E,D/E}} % that's always the same

%%% Custom styles
\tikzset{
  c1/.style={draw=blue!50,fill=blue!20},
  c2/.style={draw=green!80,fill=green!40},
  c3/.style={draw=red!80,fill=red!40}
}
\begin{document}
\begin{tikzpicture}
\drawBlob[
    mini blob=c1,
    blob={color=blue!10, label=above:Community 1},
    blob name=Comm1
    ](0,0)

\drawBlob[
    mini blob=c2,
    blob={color=green!10, label=below:Community 2},
    blob name=Comm2,
    rotate blob=-40
    ](0,-3)

\drawBlob[
    mini blob=c3,
    blob={color=red!10, label=above:Community 3},
    blob name=Comm3,
    rotate blob=-40
    ](2.5,-.5)

\foreach \start/\target in {1-C/2-A,1-D/2-D,1-E/3-A,3-C/2-E,3-E/2-B} \draw[every mini blob edge] (Comm\start) -- (Comm\target);
\end{tikzpicture}
\end{document}

Saída

insira a descrição da imagem aqui

informação relacionada