3

I am wanting to draw a block graph. A block graph (or clique tree) is a type of graph in which every biconnected component (block) is a clique. A clique is a subset of vertices (nodes) of a graph such that every two distinct vertices (nodes) in the clique are adjacent. Basically, a block graph is lots of complete subgraphs ($K_n$) joined together.

I have attached a rough sketch of the block graph I want to draw. It comprises a $K_7$, $K_5$, $K_4$, $K_1$ and two $K_3$'s. block graph

I found some code on this forum that gets me a $K_7$, $K_5$ and $K_3$. However, it doesn't quite do the trick. I only want the cliques to share one vertex, and I want them to be rotated in different positions (like in the picture.)

Furthermore, the vertices (nodes) are too big in the LateX code, and I can't seem to make them smaller, even when I change the size of the radius.

Here is my MWE:

\documentclass{article}
\usepackage{ifthen}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, positioning, calc}
\tikzset{%
    mynode/.style={%
        circle, radius=2pt, draw=darkgray, fill=white
    }
}

\begin{document}
    \begin{tikzpicture}
        \node[minimum size=4cm, regular polygon, regular polygon sides=7, rotate=180] (epta) {};
        \foreach \x in {1,2,...,7}{%
            \node[mynode] at (epta.corner \x) (e\x) {};
        }
        \foreach \x in {1,2,...,7}{%
            \foreach \y in {1,2,...,7}{%
                \ifthenelse{\x>\y}{}{\draw[darkgray] (e\x) -- (e\y);}       
        }}
        \node[below= 2pt of e1] {};
        \node[below= 2pt of e2] {};
        \node[above right = 2pt and -1pt of e3] {};
        \node[above right = 0pt and -1pt of e4] {};
        \node[above left = 0pt and -1pt of e5] {};
        \node[below left = 0pt and -1pt of e6] {};
        \node[below left = 0pt and -1pt of e7] {};
        \node(p1) at (e2) {};
        \node(p2) at (e3) {};
        
        \foreach \nextp/\prevp/\i in {p3/p2/1,p4/p3/2,p5/p4/3}{%
            \node[mynode] (\nextp) at ($(\prevp)+(77-\i*72:50pt)$) {};
        }    
        \foreach \x in {1,2,...,5}{%
            \foreach \y in {1,2,...,5}{%
                \ifthenelse{\x>\y}{}{\draw[darkgray] (p\x) -- (p\y);}       
        }}

        \node[mynode, below right = 40pt and 1pt of e2, label={[label distance=2pt]-90:}] (s1) {};
        \draw[darkgray] (e1) -- (p5) -- (s1) -- (e1);

    \end{tikzpicture}
\end{document} 

Current result:

result

Any help would be greatly appreciated!

2 Answers 2

2

This may be reinventing the wheel a bit considering how powerful the graphs library is (see Qrrbrbirlbel's solution), but here is a do-it-yourself possibility.

The command \complete[<prefix>]{<num nodes>}{<start coordinate>}{<radius of circle>}{<direction toward center>} will do what you want.

enter image description here

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}

\tikzset{
    vertex/.style={draw, thick, circle, minimum size=3mm, inner sep=0pt}
}

\newcommand{\complete}[5][]{
    \foreach \k in {1,...,#2} \node[vertex](#1\k) at ($([shift=(#5:#4)]#3)+({360/#2*(\k-1)+180+#5}:#4)$){};
    \foreach \k in {1,...,#2} \foreach \j in {1,...,\k} \draw(#1\k)--(#1\j);
} % #1=node label prefix, #2=n vertices, #3=start coordinate, #4=radius, optional #5=angle toward center
\begin{document}

\begin{tikzpicture}
\complete[N]{7}{0,0}{2cm}{0}
\complete[M]{5}{N5}{1.5cm}{30}
\complete[P]{3}{M3}{1cm}{0}
\complete[Q]{3}{M2}{1cm}{-90}
\complete[R]{2}{Q3}{.5cm}{0}
\complete[S]{4}{R2}{1cm}{0}
\end{tikzpicture}

\end{document}
1
  • Thank you so so much @Sandy G! This is exactly what I wanted!
    – Emily
    Oct 19, 2023 at 7:18
4

The graphs/graphs.standard libraries already bring a subgraph K_n which will automatically connect all nodes with each other.

With the counterclockwise key we will activate the circular placement strategy of placing nodes on a circle. It uses the value of the radius key and the phase key to place n nodes on a circle.

The custom joined subgraph K_n can then be used to “join in” another n nodes that would form with the join in node a circle of n+1 nodes.

The position key determined the position of that join in node in this new subgraph. The position 0 stands for phase 0 and the position 1 stands for the next node after the one in position 0. It's basically a phase value converted into the positions of the nodes. I was hoping this would reduce the needed calculation of the user but it is also somewhat obscure …

Note that the value for n only specifies the new nodes in the new subgraph not the total number including the join in node.


The graphs library only provides a new and shorter syntax for placing and connecting nodes. It doesn't provide any functionality that can't be done with \nodes and edges.

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{graphs.standard}
\newcommand*\tg[1]{\pgfkeysvalueof{/tikz/graphs/#1}}
\tikzgraphsset{
  show my name/.style={
    label={[node font=\tiny, inner sep=+0pt, magenta]\tikzgraphnodefullname}},
  join in/.initial=, position/.initial=0,
  declare={joined subgraph K_n}{
    [
      /utils/exec=%
        \pgfmathtruncatemacro\tgN{\tikzgraphVnum+1}%
        \pgfmathsetmacro\tgPhase{(\tg{position})*360/\tgN},
      /tikz/shift/.expanded={(\tg{join in})},
      /tikz/shift/.expanded={(\tgPhase:{-(\tg{radius})})},
    ] (\tg{join in}) --
    subgraph K_n[counterclockwise=\tgN, phase=\tgPhase+360/\tgN]}}
\begin{document}
\tikz[
  vertex/.style={
    shape=circle, draw,
    inner sep=+0pt, minimum size=+3pt}, % radius is not a shape key
  thick,
]
\graph[
  empty nodes,  % no text in nodes
  nodes=vertex, % all nodes be of style vertex
  radius=1cm,   % base radius (also default)
  nodes=show my name, % debug the names
] {
  % for the heptagraph we're using the built-in subgraph:
  %  n = 7            → seven nodes
  %  counterclockwise → arranged in a circle
  %  phase = -90      → the first one is at -90
  % this uses the radius = 1cm value to place the nodes on a circle
  % they are named “seven 1”, “seven 2”, …
         subgraph K_n[name=seven,  n=7, counterclockwise, phase=-90],
  % the next one is already a custom joined subgraph K_n
  % which always create a counterclockwise addition
  % where one of the nodes in that circle is already occupied by
  % “join in” at the “position” where position
  %  is counted from angle 0° → position = 0
  % the “n” value here is the number of additions without the “join in” node
  joined subgraph K_n[name=five,   n=4, join in=seven 3,  position=3],
  {[radius=.75cm]
    joined subgraph K_n[name=threeA, n=2, join in=five 2,   position=1.5 ],
    joined subgraph K_n[name=threeB, n=2, join in=five 1,   position=0.75],
    joined subgraph K_n[name=two,    n=1, join in=threeB 2, position=1   , radius=.5cm],
    joined subgraph K_n[name=four,   n=3, join in=two 1,    position=2   ]
  }
};
\end{document}

Output

enter image description here

2
  • 1
    +1 Always amazing to see your solutions.
    – MS-SPO
    Oct 18, 2023 at 17:27
  • Wow, thank you for your detailed response @Qrrbrbirlbel. It is very much appreciated! I like the look of the figure generated by Sandy G's code below (the size of the nodes and thickness of lines.) I'll play around with your code so that I can make it look in line with my other figures (which use nodes and edges). Thanks again!
    – Emily
    Oct 19, 2023 at 7:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .