9

I am trying to draw C. elegans germline using TikZ. I have used Philippe Goutet's / script to create "hexagon with filled round circles" enter image description here

The codes are

\documentclass[11pt]{article}
\usepackage{tikz,xcolor}
\usetikzlibrary{patterns}
\definecolor{dapi}{RGB}{0,170,255}
\def\hexagonsize{0.2cm}
\pgfdeclarepatternformonly % hexagons pattern definition
{hexagons}% name
{\pgfpointorigin}% lower left
{\pgfpoint{3*\hexagonsize}{0.866025*2*\hexagonsize}}%  upper right
{\pgfpoint{3*\hexagonsize}{0.866025*2*\hexagonsize}}%  tile size
{% shape description
\pgfsetlinewidth{0.4pt}
\pgftransformshift{\pgfpoint{0mm}{0.866025*\hexagonsize}}
\pgfpathmoveto{\pgfpoint{0mm}{0mm}}
\pgfpathlineto{\pgfpoint{0.5*\hexagonsize}{0mm}}
\pgfpathlineto{\pgfpoint{\hexagonsize}{-0.866025*\hexagonsize}}
\pgfpathlineto{\pgfpoint{2*\hexagonsize}{-0.866025*\hexagonsize}}
\pgfpathlineto{\pgfpoint{2.5*\hexagonsize}{0mm}}
\pgfpathlineto{\pgfpoint{3*\hexagonsize+0.2mm}{0mm}}
\pgfpathmoveto{\pgfpoint{0.5*\hexagonsize}{0mm}}
\pgfpathlineto{\pgfpoint{\hexagonsize}{0.866025*\hexagonsize}}
\pgfpathlineto{\pgfpoint{2*\hexagonsize}{0.866025*\hexagonsize}}
\pgfpathlineto{\pgfpoint{2.5*\hexagonsize}{0mm}}
\pgfusepath{stroke}
\pgfsetfillcolor{dapi} % setting up fill color, doesn't work with any color other than shades of gray like "gray!30"
\pgfpathcircle{\pgfpoint{1.5*\hexagonsize}{0mm}}{0.5*\hexagonsize} % adding filled circles in hexagons
\pgfpathcircle{\pgfpoint{0mm}{0.866025*\hexagonsize}}{0.5*\hexagonsize}
\pgfpathcircle{\pgfpoint{0mm}{-0.866025*\hexagonsize}}{0.5*\hexagonsize}
\pgfpathcircle{\pgfpoint{3*\hexagonsize}{0.866025*\hexagonsize}}{0.5*\hexagonsize}
\pgfpathcircle{\pgfpoint{3*\hexagonsize}{-0.866025*\hexagonsize}}{0.5*\hexagonsize}
\pgfusepath{fill}
}
    \begin{document}
\begin{tikzpicture}
\path
[fill]
[pattern=hexagons]
(16,0) -- (4,0) to [out = 180, in = 270] (1,0.95) to [out = 90, in = 180] (4,1.9) -- (16,1.9) -- cycle;
\fill[green!35] (4,0) to [out = 180, in = 270] (0.5,0.95) to [out = 90, in = 180] (4,1.9) to 
[out = 180, in = 90](1,0.95) to [out = 270, in = 180] (4,0);
\fill [blue!50](0.75,1) circle [x radius=3mm, y radius=1.5mm, rotate=60];
\end{tikzpicture}
\end{document}

My main problem is that \pgfsetfillcolor{dapi} is not working and I can not change it to anything but shades of grays. The picture depicts part of C. elegans germline with distal end on the left. Each hexagon is a cell and each filled round circle is a nucleus. The numbers at the top of the figure represent row # of the cells (are for reference only, not required). Ideally, I would want to have,

  • first 20 row circles to be filled with green with couple of red filled nuclei in row 19 and 20.
  • Row 21 to the right end should be filled with red nuclei (but see below)
  • About a third of nuclei, between row 21 and 30, to be crescent-shaped, red and randomly distributed(shown as dark blue nucleus in row 21, not generated through Tikz, but added later).
  • About 5-7 random nuclei, between row 21 and 26, to be circular and filled green.

Needless to say that my knowledge about TikZ /LaTeX is almost zero. But it seems what I have asked for is very difficult with defined patterns, but I wouldn't be surprised if some one did solve it. I would be glad if some one explains to me as how to change fill color and what I was doing wrong!

  • Patterns can't use colors. As your hexagons are different don't use a pattern. Draw each hexagons as a \node with specific parameters. – Paul Gaborit Aug 1 '17 at 16:48
  • @PaulGaborit That depends on the pattern. Some patterns can use colours; others can't. – cfr Aug 1 '17 at 17:04
  • Welcome! This is a 'form only' (colourless) pattern, so you define the colour with pattern color, when using it. See my answer below. But a pattern isn't going to work if you want the kind of variation you describe. For that, you need to start over and think in terms of nodes, pics or similar, as @PaulGaborit suggests. – cfr Aug 1 '17 at 17:12
12

There are two kinds of patterns: inherently coloured ones and colourless ones. This pattern defined as 'form only'. It isn't intended to take a colour in the definition, which is assumed to be colourless. Instead, use pattern color to set the colour when using the pattern.

\documentclass[border=10pt,11pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{patterns}
\definecolor{dapi}{RGB}{0,170,255}
\def\hexagonsize{0.2cm}
\pgfdeclarepatternformonly % hexagons pattern definition
{hexagons}% name
{\pgfpointorigin}% lower left
{\pgfpoint{3*\hexagonsize}{0.866025*2*\hexagonsize}}%  upper right
{\pgfpoint{3*\hexagonsize}{0.866025*2*\hexagonsize}}%  tile size
{% shape description
\pgfsetlinewidth{0.4pt}
\pgftransformshift{\pgfpoint{0mm}{0.866025*\hexagonsize}}
\pgfpathmoveto{\pgfpoint{0mm}{0mm}}
\pgfpathlineto{\pgfpoint{0.5*\hexagonsize}{0mm}}
\pgfpathlineto{\pgfpoint{\hexagonsize}{-0.866025*\hexagonsize}}
\pgfpathlineto{\pgfpoint{2*\hexagonsize}{-0.866025*\hexagonsize}}
\pgfpathlineto{\pgfpoint{2.5*\hexagonsize}{0mm}}
\pgfpathlineto{\pgfpoint{3*\hexagonsize+0.2mm}{0mm}}
\pgfpathmoveto{\pgfpoint{0.5*\hexagonsize}{0mm}}
\pgfpathlineto{\pgfpoint{\hexagonsize}{0.866025*\hexagonsize}}
\pgfpathlineto{\pgfpoint{2*\hexagonsize}{0.866025*\hexagonsize}}
\pgfpathlineto{\pgfpoint{2.5*\hexagonsize}{0mm}}
\pgfusepath{stroke}
\pgfsetfillcolor{dapi} % setting up fill color, doesn't work with any color other than shades of gray like "gray!30"
\pgfpathcircle{\pgfpoint{1.5*\hexagonsize}{0mm}}{0.5*\hexagonsize} % adding filled circles in hexagons
\pgfpathcircle{\pgfpoint{0mm}{0.866025*\hexagonsize}}{0.5*\hexagonsize}
\pgfpathcircle{\pgfpoint{0mm}{-0.866025*\hexagonsize}}{0.5*\hexagonsize}
\pgfpathcircle{\pgfpoint{3*\hexagonsize}{0.866025*\hexagonsize}}{0.5*\hexagonsize}
\pgfpathcircle{\pgfpoint{3*\hexagonsize}{-0.866025*\hexagonsize}}{0.5*\hexagonsize}
\pgfusepath{fill}
}
    \begin{document}
\begin{tikzpicture}
\path
[fill]
[pattern=hexagons, pattern color=dapi]
(16,0) -- (4,0) to [out = 180, in = 270] (1,0.95) to [out = 90, in = 180] (4,1.9) -- (16,1.9) -- cycle;
\fill[green!35] (4,0) to [out = 180, in = 270] (0.5,0.95) to [out = 90, in = 180] (4,1.9) to
[out = 180, in = 90](1,0.95) to [out = 270, in = 180] (4,0);
\fill [blue!50](0.75,1) circle [x radius=3mm, y radius=1.5mm, rotate=60];
\end{tikzpicture}
\end{document}

coloured pattern

However, if you need different nuclei, then you cannot do that with a pattern. You could, theoretically, draw the hexagons as a pattern and then add the nuclei separately. However, that would probably be rather error-prone, even if slightly faster in terms of compilation time. It is probably easier and more robust to draw the nuclei along with the hexagonal cell containing it. That way, you can introduce as much variety as you like.

For example,

\documentclass[border=10pt,11pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\definecolor{dapi}{RGB}{0,170,255}
\begin{document}
\begin{tikzpicture}
  [
    hexa/.style={draw=dapi, minimum size=\hdim, inner sep=0pt, regular polygon, regular polygon sides=6, anchor=center},
    nucleus/.style={fill, minimum size=.35*\hdim, inner sep=0pt, circle, anchor=center},
  ]
  \begin{scope}
    \clip (16,0) coordinate (d) -- (4,0) coordinate (a) to [out = 180, in = 270] (1,0.95) coordinate (b) to [out = 90, in = 180] (4,1.9) coordinate (c) -- (d |- c) -- cycle (b |- c) coordinate (h0-0);
    \newdimen\hdim
    \newdimen\odim
    \hdim=3mm
    \pgfmathsetlength\odim{0.866025*\hdim}
    \foreach \j [remember=\j as \jlast (initially 0)] in {1,...,70}
    \foreach \i [remember=\i as \ilast (initially 0) ] in {1,...,8}
    {
      \ifodd\j\def\tempa{30}\else\def\tempa{-30}\fi
      \ifnum\j<21\def\tempb{green}\else\def\tempb{red}\fi
      \ifnum\j=19\ifnum\i=3\def\tempb{red}\fi\ifnum\i=7\def\tempb{red}\fi\fi
      \ifnum\j=20\ifnum\i=1\def\tempb{red}\fi\ifnum\i=5\def\tempb{red}\fi\ifnum\i=8\def\tempb{red}\fi\fi
      \ifnum\j=22\ifnum\i=4\def\tempb{green}\fi\fi
      \ifnum\j=24\ifnum\i=7\def\tempb{green}\fi\fi
      \ifnum\j=25\ifnum\i=6\def\tempb{green}\fi\fi
      \ifnum\j=24\ifnum\i=2\def\tempb{green}\fi\fi
      \ifnum\j=26\ifnum\i=3\def\tempb{green}\fi\fi
      \ifnum\j=21\ifnum\i=5\def\tempb{green}\fi\fi
      \ifnum\i=1
        \ifnum\j=1\path (h0-0) node (h\j-\i) [hexa] {} node [nucleus, \tempb] {};
        \else\path ([shift=(\tempa:\odim)]h\jlast-1) node (h\j-\i) [hexa]  {} node [nucleus, \tempb] {};
        \fi
      \else\path ([yshift=-\odim]h\j-\ilast) node (h\j-\i) [hexa] {} node [nucleus, \tempb] {};
      \fi
    };
  \end{scope}
  \fill[green!35] (a) to [out = 180, in = 270] (0.5,0.95) to [out = 90, in = 180] (c) to
  [out = 180, in = 90] (b) to [out = 270, in = 180] (a);
  \fill [blue!50] (0.75,1) circle [x radius=3mm, y radius=1.5mm, rotate=60];
\end{tikzpicture}
\end{document}

various nuclei

  • Thanks for the beautiful and very efficient code, you have almost got me there. Now I am trying to fully understand the code, and hopefully, be able to add some changes. – A. Khan Aug 2 '17 at 1:53
6

Here is my final picture based on the answer from @cfr with little changes to include crescent nuclei, with random rotations, after meiotic entry. Might be useful for some. Distal gonadal arm of *C. elegans* germline

The codes are,

\documentclass[border=10pt,11pt]{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\definecolor{dapi}{RGB}{0,170,255}
\begin{document}
\begin{tikzpicture}
  [
    hexa/.style={draw=dapi, minimum size=\hdim, inner sep=0pt, regular polygon, regular polygon sides=6, anchor=center},
    nucleus/.style={fill, minimum size=.5*\hdim, inner sep=0pt, circle, anchor=center},
    crescent/.style={fill = white, minimum size=.35*\hdim, inner sep=0pt, circle, anchor=south}
  ]
  \begin{scope}
    \clip (16,0) coordinate (d) -- (4,0) coordinate (a) to [out = 180, in = 270] (1,0.95) coordinate (b) to [out = 90, in = 180] (4,1.9) coordinate (c) -- (d |- c) -- cycle (b |- c) coordinate (h0-0);
    \newdimen\hdim
    \newdimen\odim
    \hdim=3.5mm
    \pgfmathsetlength\odim{0.866025*\hdim}
    \def\tempc{0}
    \foreach \j [remember=\j as \jlast (initially 0)] in {1,...,70}
    \foreach \i [remember=\i as \ilast (initially 0) ] in {1,...,8}
    \pgfmathsetseed{\j+\i} % for reproducibility
    \pgfmathrandominteger{\k}{1}{360} % k is (randomly) defind to rotate crescent nuclei
    {
      \ifodd\j\def\tempa{30}\else\def\tempa{-30}\fi
      \ifnum\j<21\def\tempb{green}\else\def\tempb{red}\fi
      \ifnum\j=19\ifnum\i=3\def\tempb{red}\fi\fi % tempb - to add red nuclei in progenitor zone and green nuclei in leptotene/zygotene
      \ifnum\j=20\ifnum\i=5\def\tempb{red}\fi\fi
      \ifnum\j=21\ifnum\i=5\def\tempb{green}\fi\fi
      \ifnum\j=22\ifnum\i=4\def\tempb{green}\fi\fi
      \ifnum\j=24\ifnum\i=7\def\tempb{green}\fi\fi
      \ifnum\j=25\ifnum\i=6\def\tempb{green}\fi\fi
      \ifnum\j=24\ifnum\i=2\def\tempb{green}\fi\fi
      \ifnum\j=26\ifnum\i=3\def\tempb{green}\fi\fi
      \ifnum\j=21\ifnum\i=4\def\tempc{1}\fi\fi % tempc for adding crescent shaped nuclei in laeptotene/zygotene region
      \ifnum\j=21\ifnum\i=6\def\tempc{1}\fi\fi      
      \ifnum\j=22\ifnum\i=2\def\tempc{1}\fi\fi
      \ifnum\j=22\ifnum\i=5\def\tempc{1}\fi\fi      
      \ifnum\j=22\ifnum\i=7\def\tempc{1}\fi\fi      
      \ifnum\j=23\ifnum\i=2\def\tempc{1}\fi\fi      
      \ifnum\j=23\ifnum\i=6\def\tempc{1}\fi\fi      
      \ifnum\j=23\ifnum\i=7\def\tempc{1}\fi\fi      
      \ifnum\j=24\ifnum\i=1\def\tempc{1}\fi\fi      
      \ifnum\j=24\ifnum\i=4\def\tempc{1}\fi\fi      
      \ifnum\j=25\ifnum\i=3\def\tempc{1}\fi\fi      
      \ifnum\j=25\ifnum\i=4\def\tempc{1}\fi\fi      
      \ifnum\j=25\ifnum\i=7\def\tempc{1}\fi\fi      
      \ifnum\j=26\ifnum\i=1\def\tempc{1}\fi\fi      
      \ifnum\j=26\ifnum\i=5\def\tempc{1}\fi\fi      
      \ifnum\j=27\ifnum\i=3\def\tempc{1}\fi\fi      
      \ifnum\j=27\ifnum\i=5\def\tempc{1}\fi\fi      
      \ifnum\j=28\ifnum\i=2\def\tempc{1}\fi\fi      
      \ifnum\j=28\ifnum\i=5\def\tempc{1}\fi\fi      
      \ifnum\j=28\ifnum\i=6\def\tempc{1}\fi\fi      
      \ifnum\j=29\ifnum\i=5\def\tempc{1}\fi\fi      
      \ifnum\j=31\ifnum\i=2\def\tempc{1}\fi\fi
      \ifnum\i=1
        \ifnum\j=1\path (h0-0) node (h\j-\i) [hexa] {} node [nucleus, \tempb] {} node [crescent, rotate=\k,opacity = \tempc] {};
        \else\path ([shift=(\tempa:\odim)]h\jlast-1) node (h\j-\i) [hexa]  {} node [nucleus, \tempb] {} node [crescent, rotate=\k,opacity = \tempc] {};
        \fi
      \else\path ([yshift=-\odim]h\j-\ilast) node (h\j-\i) [hexa] {} node [nucleus, \tempb] {}
      node [crescent, rotate=\k,opacity = \tempc] {};
      \fi
    };
  \end{scope}
  \fill[pink!45] (a) to [out = 180, in = 270] (0.5,0.95) to [out = 90, in = 180] (c) to
  [out = 180, in = 90] (b) to [out = 270, in = 180] (a);
  \fill [dapi] (0.75,1) circle [x radius=3mm, y radius=1.5mm, rotate=60];
  \node[above, rotate=90] (DTC) at (0.5,0.95) {DTC};
  \node[below, rotate = -30] (ME) at (6.4,0) {ME};
  \draw[dashed, ultra thick, color = blue] (6.13,1.9) -- (6.13,0);
  \node[above] (pz) at (4,1.9) {Progenitor Zone};
  \node[above] (lz) at (7,1.9) [align=left]{Leptotene/ \\Zygotene};
  \node[above] (pachytene) at (10,1.9) {Pachytene};
\end{tikzpicture}
\end{document}

Thanks again to @cfr and @PaulGaborit.

  • This is very nice - thanks for posting your final solution! – cfr Aug 17 '17 at 11:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.