Anmerkungen:

Anmerkungen:

Ich habe den folgenden TikZ-Code und frage mich, ob er optimiert werden kann? (Ich bin mir eigentlich sicher, dass das möglich ist!)

Das Hauptproblem ist folgendes: Wenn ich die erste Gruppe von Knoten, die von der Ellipse umgeben sind, drehe, um die zweite Gruppe zu erstellen, ist die Ellipse nicht am richtigen Platz. (Sie ist nicht dort, wo ich sie erwarte. Ich bin nicht sicher, welcher Punkt bei der Drehung fixiert ist.) Ich muss sie blind anpassen, um sie an die gewünschte Stelle zu verschieben.

Dasselbe gilt für die Beschriftungen „Community 2“ und „Community 3“. Die gedrehten Koordinaten scheinen nicht mit meinen Erwartungen übereinzustimmen, und ich muss sie blind mit begrenztem Erfolg anpassen.

Eine Anmerkung, die nichts damit zu tun hat: Ich habe auch mit For-Schleifen experimentiert, aber da ich möchte, dass die Kanten in jeder Community leicht unterschiedlich sind, scheint ein direktes Kopieren und Einfügen einfacher zu sein?

Auch andere Optimierungen sind willkommen.

Code

\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}

Ausgabe

Bildbeschreibung hier eingeben

Antwort1

Um die Zeichnung wiederverwenden zu können, sollten Sie ein Makro für sie definieren:

Bildbeschreibung hier eingeben

Anmerkungen:

  • Da ich den Zweck der Zeichnung nicht kenne und nicht weiß, wie sorgfältig Sie Platzierung und Konnektivität wählen möchten, habe ich mich an dem angegebenen Code orientiert.
  • Bei sich wiederholenden Aufgaben ist zu beachten, dass jede Aufgabe auf ähnliche Weise betrachtet werden sollte. Beim Platzieren des Knotentexts verwenden Sie beispielsweise zweimal absolute Koordinaten und beim dritten Mal eine relative Platzierung. Ich habe mich für die absolute Position entschieden, aber das ist möglicherweise nicht ideal. Dadurch wurde die Platzierung der dritten Knotenbeschriftung natürlich zu einer Art Ratespiel durch Ausprobieren. Im Relative Placement of Labelsfolgenden Abschnitt finden Sie eine möglicherweise bessere Option.
  • Die Knoten werden mit A<color>, … D<color>(wobei <color>der dritte Parameter für ist \MyNodes) gekennzeichnet, sodass sie systematisch benannt und dann auch außerhalb der Knotenzeichnung beliebig referenziert werden können.

Code: Feste Platzierung der Etiketten

\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}

Sie können die Knotenbeschriftungen auch relativ platzieren, was meiner Meinung nach eine bessere Option ist. Um zu bestimmen, wo die Beschriftungen platziert werden sollen, ist es hilfreich zu wissen, welche Beschriftungen sich wo befinden, und das \Debugfolgende Makro ermöglicht Ihnen, dies zu sehen. Wenn Sie die nachfolgende Zeile im MWE auskommentieren, werden die Knotenbeschriftungen unterdrückt.

Bildbeschreibung hier eingeben

Code: Relative Platzierung von Beschriftungen

\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}

Antwort2

Erneuter Optimierungsversuch. Dabei kommen PGF-Schlüssel zum Einsatz.

Haftungsausschluss: Das Ergebnis ist nicht genau dasselbe, da ich den ellipseKnoten anstelle des ellipsePfads verwendet habe (und die Koordinaten ein wenig anpassen musste).
Der Vorteil, den ich hier sah, war die labelMöglichkeit, die „Community“-Beschriftungen hinzuzufügen. Außerdem können Sie darauf für die spätere Verwendung verweisen.

Es gibt einen Befehl:

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

Das (<coordinate>)ist der Ort (0,0)des lokalen Koordinatensystems.
Da im Bild einige Transformationen stattfinden, bin ich mir nicht ganz sicher, wo die Blobs sind. Beachten Sie nur, dass sich der erste Mini-Blob ( A) ohne Rotation bei befinden wird (<coordinate>).

Sie können die Stile verwenden

  • every blob picture,
  • every mini blob,
  • every blob, Und
  • every mini blob edge

um den Inhalt anzupassen. Diese sind ähnlich aufgebaut wie die every nodeStyles. Zu jedem every <something>Style gibt es einen <something>Style, der sein Element an den entsprechenden everyStyle anfügt.

Darüber hinaus gibt es noch drei weitere Schlüssel:

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

Die rotate blobTaste dreht das gesamte Bild (den großen Blob und die Mini-Blobs) um die Mitte des großen Blobs.

Der Wert des blob nameSchlüssels wird zur Benennung des großen Blobs (der nach dem Schlüssel benannt ist) und der Mini-Blobs (die dort benannt sind, <value of blob name>-<char>wo <char>zwischen Aund steht E) verwendet.

Wenn blob namenicht angegeben (z. B. leer, wenn kein Standardname angegeben ist), erhalten die Knoten einen internen Namen (unter dem sie später immer noch aufgrund eines internen Zählers referenziert werden können).
Der Zähler wird nicht wirklich benötigt, wenn die Knoten später nicht referenziert werden …

Schließlich gibt es noch connect mini blobs. Dieser Schlüssel sollte eine Liste von Mini-Blobs erhalten, die innerhalb des Blobs verbunden werden sollen.
Da Ihr Beispiel darauf hinzuweisen scheint, dass sie immer auf die gleiche Weise verbunden werden, habe ich diesen Stil mit voreingestellt

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

Dies zeigt den Vorteil der Verwendung von PGF-Schlüsseln. Sie können Standardwerte festlegen, Sie können sie mitten im Dokument ändern, Sie können .appendEinstellungen vornehmen und Sie können für jeden neuen Blob unterschiedliche Einstellungen haben.

Sie können auch mini blob <char>Stile festlegen, um jeden Mini-Blob weiter anzupassen.

Und es gibt every minin blob edge, für die Linie die nach innen gezeichneten Kanten zwischen den Mini-Blobs.

VerbesserungenoderVielleicht die fitBibliothek?

Fällt Ihnen auf, dass beim Zeichnen der Mini-Blobs ähnliche Linien entstehen?

Eine Verbesserung wäre, auch die Anzahl und den Standort dieser Mini-Blobs anzupassen. Ein paar Tasten und eins \foreachwürden genügen.

Die Ellipse kann dann – mit Hilfe der Bibliothek – mit (z. B. ) backgroundgezeichnet werden , allerdings muss die Rotation dieser Ellipse manuell definiert werden und die tatsächliche Größe hängt von ab . Auch hier finden zu viele Transformationen statt.fitfit=(\qrr@blob@name-A)(\qrr@blob@name-B)…rotate blob

Code

\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}

Ausgabe

Bildbeschreibung hier eingeben

verwandte Informationen