share
TeX - LaTeXHow can I draw nucleosomes with wrapped DNA in tikz or pstricks?
[+32] [3] GTK
[2012-12-05 03:27:04]
[ tikz-pgf pstricks 3d ]
[ https://tex.stackexchange.com/questions/85576/how-can-i-draw-nucleosomes-with-wrapped-dna-in-tikz-or-pstricks ]

The nucleosome is the fundamental unit of DNA packing in cells, and I am trying to generate some figures for regular use in manuscripts and presentations. The nucleosome is commonly abstracted to a drawing in one of two ways. One representation is as it appears in Wikipedia [1] Creative Commons nucleosome image by Wikipedia user Darekk2

drawn as a core of eight spheres (representing the core histone octamer), with a two wraps of DNA and a ninth histone (H1). Sometimes the proteins are further abstracted to a cylinder or just a single sphere so that several adjacent nucleosomes packing DNA can be illustrated. That's what I'm trying to achieve. Very often the cylinder is tilted, like in this extremely impoverished tikz attempt. I would be thrilled to keep the multiple histone proteins, but it may be too challenging.

 \documentclass{standalone}
 \usepackage {tikz}
 \usetikzlibrary{shapes}
 \begin {document}
 \tikzset{nucleosome core/.style={cylinder, 
     rotate=30,shape aspect=0.5,minimum width=1cm,
     minimum height=0.7cm, cylinder uses custom fill,
     cylinder end fill=red!50,cylinder body fill=red!25}}
 \begin{tikzpicture}
 \foreach \i in {0,2,4,6} { 
   \path node [nucleosome core] at (\i,0) {} edge [bend right] (\i + 1.7,0);
 }
   \end{tikzpicture}
 \end{document}

nucleosome

Here the DNA linking adjacent nucleosomes is evident, but it is missing the DNA wrapping, which is really essential because that's what the nucleosome does.

I think to get to something like the Wikipedia version I'd need to use pstricks, though I normally use tikz for figures and would be willing to trade 3D realism for familiarity. At a minimum, I'd like my cylinder-tikz version to include the wrappings.

[EDIT: I added a bounty because, while I recognize the particular question may be of limited interest to the larger TeX.SX community, I think I'd learn a lot from better efforts than my current best shot. If more inspiration is needed, here [2] is an example of some nucleosomes as cylinders, and here [3] with epigenetic marks decorating nucleosomes.]

(4) As we saw in 3d-helix-torus-with-hidden-lines, PSTricks will be the way forward; it's hard to do the hidden parts in tikz - cmhughes
you may be right, but I am still flummoxed - GTK
[+26] [2012-12-12 09:51:43] Mark Wibrow [ACCEPTED]

Definitely not perfect, and it mostly could/should be parameterised (and the `frontwrapping' layer is arguably unecessary):

\documentclass{article}
\usepackage{tikz}

\begin{document}

\pgfdeclarelayer{backwrapping}
\pgfdeclarelayer{frontwrapping}
\pgfsetlayers{backwrapping,main,frontwrapping}

\tikzset{
    wrapping/.style={
        draw=black!60, 
        line cap=round, 
        line join=round, 
        ultra thick},
    nucleosome/.style={
        fill=red!40, 
        fill opacity=.9, 
        draw=none},
    top cylinder/.style={
        fill=red!60, 
        fill opacity=.9
    }
}


\begin{tikzpicture}[scale=0.75]

\foreach \q [remember=\q as \p] in {1, 2, 3, 4}{

\begin{scope}[shift={(\q*3,0)}, rotate=30]
\path [nucleosome] 
    (0,1) 
    arc (90:270:0.375 and 1) -- (1.25,-1) 
    arc (270:90:0.375 and 1) -- cycle;
\path [top cylinder] 
    (1.625, 0) arc (0:360:0.375 and 1) -- cycle;

\begin{scope}[shift={(0.25,0)}]
\begin{pgfonlayer}{backwrapping}
\draw [wrapping] 
    (0.25, -1.125) 
    \foreach \i in {180,185,...,360}{ -- (\i/720+0.375*sin -\i, 1.125*cos \i)};
\draw [wrapping] (0, 1.125)  arc(90:0:0.125cm and 0.25cm) arc(0:-90:1cm and 1cm) coordinate (wrapping-start-\q);
\end{pgfonlayer}

\begin{pgfonlayer}{frontwrapping}
\draw [wrapping] 
    (0, 1.125)  
    \foreach \i in {0,5,...,180}{ -- (\i/720+0.375*sin -\i,1.125*cos \i)}
    [shift={(0.5,0)}]
    (0, 1.125) 
    \foreach \i in {0,5,...,150}{ -- (\i/720+0.375*sin -\i,1.125*cos \i)} coordinate (wrapping-end-\q);
\end{pgfonlayer}
\end{scope}
\ifnum\q>1
    \draw [wrapping] (wrapping-end-\p) .. controls ++(-60:0.5cm)  and ++(180:0.25cm) .. (wrapping-start-\q);
\fi
\ifnum\q=4
\draw [wrapping] (wrapping-end-\q) arc (210:270:1cm and 0.75cm);
\fi
\end{scope}
}

\end{tikzpicture}

\end{document}

I can't post an image but drawing the linking between adjacent nucleosomes was done by trial and error, so not ideal. I can `sort of' see how it could be done automatically, but I was too lazy.

EDIT by mwibrow. Removed (initially 0) as it is buggy in some PGF versions.


EDIT by JLDiaz. Since the author has not enough reputation to post an image, I'm doing so for him. In order to generate this image a small modification had to be done in the source code. The option (initially 0) was removed in the \foreach loop.

Result


(1) I can't get this to compile properly, for me it complains that No shape named wrapping-end-0 is known. If I set initally 1 instead of initially 0, it compiles, but there's something wrong with the connections of the helices. Apart from that, it looks really good though! - Jake
@Jake Apparently the convenient syntax remember ... as does not work always as expected. See for example Iterate with \foreach over multiple variables and '\remember' one of them does not work as expected which describes this very problem. Applying the same solution (using \xdef) I managed to compile it and produced the right image. Shoud I edit the answer and upload the image? - JLDiaz
Hmm... compiles for me. Perhaps \foreach \q/\p in {1/0,2/1,3/2,4/3} works better? - Mark Wibrow
@JLDiaz, @mwibrow: Ah yes, seems to be the same issue. It actually works for me if I just remove the initially 0 bit, since the initial value defaults to 0 anyway. The \foreach \q/\q... approach also works. Not sure what's going on here: mwibrow, are you using a more recent PGF version than 2.1 (the CVS, perchance)? - Jake
(1) @mwibrow I edited your post to upload an image, but I didn't touch your code. You could remove the (initially 0) yourself and remove that part of my edit. Great solution btw! - JLDiaz
(2) @mwibrow: Oh, by the way, a very warm welcome to the site, it's great to see you here! And thanks for the huge amount of work you put into PGF. You may have noticed, there are quite a large number of avid TikZ/PGF fans on this site... - Jake
Wow, this is great! For the record, the superhelical wrapping around a standard nucleosome is left handed, not right handed, which is why my (much, much worse) solution looks reversed. But, wow. - GTK
@Jake: yep, I am using a CVS version. - Mark Wibrow
1
[+21] [2012-12-07 18:34:49] JLDiaz

There is one of my "hackish" solutions, not to be taken too seriously.

I'll show first the result, then the high-level code, then the ugly macro which draws one cylinder and its wrapping, and finally the explanations about how I did it all.

1. The result

Result

2. High level tikzpicture

It contains a loop in which a strand is drawn from previous nucleosome to the current one, then the nucleosome is drawn on top, and finally some coordinate points are set up for the next iteration.

% Define styles, colors and opacity
\tikzset{
  wrapping/.style = {draw=black!60, line cap=round, line join=round, ultra thick},
  nucleosome/.style = {red!40, fill opacity=.9, draw=none},
  top cylinder/.style= {red!60, fill opacity=.9}
}

\begin{tikzpicture} % Draw the chain
\coordinate (previous) at (-1,0) {};
\coordinate (start) at (-.235,.423) {};
\foreach \x in {0,2,4,6} {  % Draw four nucleosomes, 2cm apart each other
  \begin{scope}[xshift=\x cm]
  \draw[wrapping] (previous) to[out=-50, in=-60] (start); % connection from previous
  \nucleosome                                             % Black magic here
  \coordinate (previous) at (end) {};                     % update join points
  \coordinate (start) at ([xshift=2cm] start) {};
  \end{scope}
}
% Last strand
\draw[wrapping] (previous) to[out=-50, in=-60] +(1,.3); 
\end{tikzpicture}

3. \nucleosome macro

Be warned, it is ugly. After it, the explanation of where the numbers came from:

\def\nucleosome{
\draw[wrapping](.198,-.549)--(.204,-.543)--(.225,-.519)--(.243,-.49)--(.26,-.457)--(.274,-.42)--(.285,-.379)--(.294,-.335)--(.3,-.288)--(.303,-.238)--(.304,-.186)--(.302,-.133)--(.297,-.078)--(.29,-.023)--(.281,.033)--(.27,.089)--(.256,.143)--(.24,.197)--(.223,.249)--(.204,.299)--(.184,.347)--(.163,.391)--(.14,.432)--(.117,.47)--(.094,.504)--(.071,.533)--(.047,.558)--(.024,.578)--(.002,.593)--(-.012,.599);
\draw[wrapping](-.235,.423)--(-.259,.449)--(-.282,.471)--(-.305,.488)--(-.325,.499);
%\filldraw[fill=green](-.235,.423) circle (2pt);
\coordinate (start) at (-.235,.423) {};
\filldraw[top cylinder](.422,-.414)--(.499,-.422)--(.561,-.379)--(.6,-.288)--(.614,-.159)--(.6,-.003)--(.561,.163)--(.499,.324)--(.422,.464)--(.336,.569)--(.251,.629)--(.173,.638)--(.112,.595)--(.072,.504)--(.059,.374)--(.072,.218)--(.112,.052)--(.173,-.109)--(.251,-.249)--(.336,-.354)--cycle;
\filldraw[nucleosome](-.561,.379)--(.112,.595)--(.173,.638)--(-.499,.422)--cycle;
\draw[wrapping](-.325,.499)--(-.327,.5)--(-.348,.507)--(-.368,.509)--(-.386,.505)--(-.391,.503);
\filldraw[nucleosome](-.173,-.638)--(.499,-.422)--(.422,-.414)--(-.251,-.629)--cycle;
\draw[wrapping](.112,-.59)--(.129,-.587)--(.156,-.578)--(.181,-.563)--(.198,-.549);
\draw[wrapping](-.012,.599)--(-.02,.603)--(-.041,.609)--(-.06,.609)--(-.077,.604);
\filldraw[nucleosome](-.6,.288)--(.072,.504)--(.112,.595)--(-.561,.379)--cycle;
\draw[wrapping](-.391,.503)--(-.403,.497)--(-.418,.484)--(-.431,.466)--(-.441,.443)--(-.45,.415)--(-.454,.392);
\filldraw[nucleosome](-.251,-.629)--(.422,-.414)--(.336,-.354)--(-.336,-.569)--cycle;
\draw[wrapping](-.059,-.538)--(-.057,-.54)--(-.024,-.56)--(.009,-.575)--(.04,-.586)--(.071,-.592)--(.101,-.592)--(.112,-.59);
\draw[wrapping](-.077,.604)--(-.078,.604)--(-.094,.594)--(-.108,.579)--(-.121,.559)--(-.131,.535)--(-.138,.506)--(-.14,.493);
\filldraw[nucleosome](-.614,.159)--(.059,.374)--(.072,.504)--(-.6,.288)--cycle;
\filldraw[nucleosome](-.336,-.569)--(.336,-.354)--(.251,-.249)--(-.422,-.464)--cycle;
\draw[wrapping](-.454,.392)--(-.456,.384)--(-.46,.348)--(-.461,.309)--(-.459,.267)--(-.459,.264);
\filldraw[nucleosome](-.6,.003)--(.072,.218)--(.059,.374)--(-.614,.159)--cycle;
\filldraw[nucleosome](-.422,-.464)--(.251,-.249)--(.173,-.109)--(-.499,-.324)--cycle;
\draw[wrapping](-.167,-.438)--(-.155,-.452)--(-.122,-.486)--(-.089,-.515)--(-.059,-.538);
\filldraw[nucleosome](-.561,-.163)--(.112,.052)--(.072,.218)--(-.6,.003)--cycle;
\filldraw[nucleosome](-.499,-.324)--(.173,-.109)--(.112,.052)--(-.561,-.163)--cycle;
\draw[wrapping](-.459,.264)--(-.455,.222)--(-.448,.175)--(-.438,.125)--(-.433,.105);
\draw[wrapping](-.14,.493)--(-.144,.473)--(-.146,.436)--(-.147,.396)--(-.145,.365);
\draw[wrapping](-.269,-.298)--(-.248,-.331)--(-.218,-.375)--(-.187,-.415)--(-.167,-.438);
\draw[wrapping](-.433,.105)--(-.426,.074)--(-.411,.022)--(-.394,-.03)--(-.38,-.069);
\draw[wrapping](.146,-.337)--(.17,-.363)--(.202,-.395)--(.235,-.423);
%\filldraw[fill=green](.235,-.423) circle (2pt);
\coordinate (end) at (.235,-.423) {};
\draw[wrapping](-.355,-.131)--(-.353,-.135)--(-.329,-.187)--(-.304,-.237)--(-.277,-.285)--(-.269,-.298);
\draw[wrapping](-.38,-.069)--(-.375,-.083)--(-.355,-.131);
\draw[wrapping](-.145,.365)--(-.144,.353)--(-.139,.307)--(-.131,.259)--(-.121,.209)--(-.12,.205);
\draw[wrapping](.044,-.197)--(.047,-.2)--(.076,-.246)--(.106,-.288)--(.138,-.328)--(.146,-.337);
\draw[wrapping](-.12,.205)--(-.108,.158)--(-.092,.105)--(-.074,.053)--(-.066,.032);
\draw[wrapping](-.04,-.031)--(-.032,-.052)--(-.007,-.103)--(.019,-.153)--(.044,-.197);
\draw[wrapping](-.066,.032)--(-.054,0)--(-.04,-.031);
}

4. The explanations

First of all, inspired by @cmhughes comment, I wrote a sketch program to draw a single nucleosome, with part of a helix around it. I marked also with a big green dot the start and end of the helix. These will be the "connecting points" from one nucleosome to the next one. This is the sketch code, note that I use line style=wrapping or fill style=nucleosome to be able to customize the style later from tikz.

def start_angle 180       % starting and ending angles of the helix
def end_angle 720-180
def radius_helix 1.08     % helix radius, a bit more than the cylinder
def cylinder_height 1.4   
def percentage_wrapped 70 % How many of the cylinder is wrapped in the helix
def start_point (radius_helix*cos(start_angle), 
                 -percentage_wrapped/100*cylinder_height/2,
                 radius_helix*sin(start_angle))

def helix {
  def n_segs 100
  sweep [line style=wrapping]
     { n_segs, translate([0, cylinder_height*percentage_wrapped/100/n_segs,0]),
               rotate(end_angle/n_segs, [0,1,0]) } (start_point)
}

def start {  % Starting point of the helix
  dots [fill=green](start_point)
}

def end {    % Ending point of the helix
  put { translate([0, cylinder_height*percentage_wrapped/100,0]) 
        then rotate(end_angle, [0,1,0]) } {{start}}
}

def cylinder {
  def n_cyl_segs 20
  sweep[fill style=top cylinder]{ n_cyl_segs<>,
        rotate(360/n_cyl_segs, [0,1,0]) }
        line[fill style=nucleosome](1,-cylinder_height/2)(1,cylinder_height/2)
}

def nucleosome {
  put { rotate (-60, [1, 0, 0])} {{cylinder}{helix}{start}{end}}
}

put { view((10,15,0)) } { {nucleosome} }  % Draw it!

global { language tikz }

I processed the above file with the command:

sketch nucleosome.sketch > nucleosome.tex

Then included the result in the document:

\documentclass{article}
\usepackage{tikz}
\tikzset{
  wrapping/.style = {draw=black!60, line cap=round, line join=round, ultra thick},
  nucleosome/.style = {red!40, fill opacity=.9, draw=none},
  top cylinder/.style= {red!60, fill opacity=.9}
}
\begin{document}
\input nucleosome
\end{document}

And got (please, note the green big dots):

Nucleosome

Then edited nucleosome.tex and searched for the string green. I found:

[...]
\filldraw[fill=green](-.235,.423) circle (2pt);
[...]
\filldraw[fill=green](.235,-.423) circle (2pt);
[...]

This gave me the coordinates in the 2D projection of the starting and ending point of the nucleosome wrapping. I manually replaced those lines with:

[...]
%\filldraw[fill=green](-.235,.423) circle (2pt);
\coordinate (start) at (-.235,.423) {};
[...]
%\filldraw[fill=green](.235,-.423) circle (2pt);
\coordinate (end) at (.235,-.423) {};
[...]

Then replaced the \begin{tikzpicture} with \def\nucleosome{ and the \end{tikzpicture} with } to get the definition of the \nucleosome macro, already shown in section 3. The rest should be clear.


That's just lovely. I've adopted it (with some changes, in particular to make the superhelix left handed) in the figures I'm prepping. Even though you say it's "not to be taken too seriously", I expect you'll win the bounty. - GTK
I'm glad that my answer was actually useful. I found the proccess too convoluted, hence my "not to be taken too seriously" note. If you are satisfied with the answer you can accept it (check mark below the vote count). The bounty will go automatically to the accepted answer if you don't assign it manually before. - JLDiaz
I was hoping someone would provide a pstricks answer, since I don't use pstricks. But I hadn't used sketch before either, so that was fun. - GTK
2
[+13] [2012-12-06 07:39:46] GTK

I'll attempt to answer my own question, although it is still pretty inadequate. A poor person's DNA wrapping can be achieve with some bent paths along the cylinders (my first use of the angles instead of named anchors). But the connection between the wrapping and the linking strand is a hack at best.

 \documentclass{standalone}
 \usepackage {tikz}
 \usetikzlibrary{shapes,backgrounds}
 \begin {document}
 \tikzset{nucleosome core/.style={cylinder,
     rotate=150,
     shape aspect=0.5,minimum width=1cm,
     minimum height=0.7cm, cylinder uses custom fill,
     cylinder end fill=red!50,cylinder body fill=red!25}}

 \tikzset {DNA wrap/.style= {ultra thick, draw,color=gray,line cap=round}}

 \begin{tikzpicture}
 \foreach \i in {0,2,4,6} { 
   \path node [nucleosome core] (\i) at (\i,0) {} ;
   \begin{pgfonlayer} {background}
     \draw (\i-1.7,0) edge [DNA wrap, bend right=55] (\i.70);
   \end{pgfonlayer}
   \draw [DNA wrap] (\i.70) edge [bend right=15] (\i.285);
   \draw [DNA wrap] (\i.95) edge [bend right=15] (\i.260);
 }
   \end{tikzpicture}
 \end{document}

Which results in this (edit: fixed handedness of wrapping and added background layer)

TODO: names for nucleosomes so they can be decorated with epigenetic marks (reading Amy Hendrickson "The joy of \csname...\endcsname" in TUGBoat 33(2):219)


3