Exploring ChemFig: Customising appearance

In my previous post, I looked at the basics of using the ChemFig package to create chemical structures. I finished that post with a structure that is complete but which I think does not look great compared with the reference version I created in ChemDraw. (There’s a MyChemistry entry that looks at similar customisation: worth a look!)

Atom placement

The first issue to tackle is the placement of atom labels. ChemFig ‘detects’ atoms, so that the labels are correctly centred relative to bonds. However, that does not work with numbered R-groups, as the numbers need to be ‘ignored’ for alignment purposes. This is a pretty common requirement, so ChemFig provides a way to ‘split’ labels, using |:

\chemfig{
  *6(-(-R|^2)=-
    (-=[::-60]N-*6(=(-R|^3)-=(-R|^4)-=(-R|^3)-))
  =(-OH)-(-R|^1)=)
}

which gives the output

To see the difference here, look at for example R2 here compared to the version in the previous post: it’s subtle, but it is there!

Atom spacing and bond width

The standard settings for ChemFig share a ‘feature’ with those for ChemDraw: they don’t look very good! As I said in the previous post, I use the Royal Society of Chemistry’s template for my structures, as I think they look much better. The template uses 7 pt text, and so the lengths, etc. all match that size. For use in LaTeX, I want things to be more flexible so wanted to convert the values into em (i.e. relative dimensions based on font size).

There are three key dimensions used by both ChemDraw and ChemFig to set how bonds look: the bond length, the line width and the gap between lines when drawing double bonds. There is also a ‘margin’ used between atom labels and bonds, so the two don’t touch. After a bit of work doing the calculation (using to the LaTeX3 FPU), I found that

\setdoublesep{0.35700 em}  % 'Bond Spacing'
\setatomsep{1.78500 em}    % 'Fixed Length'
\setbondoffset{0.18265 em} % 'Margin Width'
\newcommand{\bondwidth}{0.06642 em} % 'Line Width'
\setbondstyle{line width = \bondwidth}

was the right set up. The comments are the ChemDraw names for settings, and I’ve set the line width as a command as it turns out I’ll want it again for some more advanced things to be covered in the next post.

The central double bond

Changing the bond spacing shows up another issue: the central double bond is not right. Rather than bond to the ‘middle’ of the double bond, we want the chain to choose one ‘side’. That can be done using either _ or ^, depending on which side is required. I decided to match the ChemDraw version using

\chemfig{
  *6(-(-R|^2)=-
    (-=^[::-60]N-*6(=(-R|^3)-=(-R|^4)-=(-R|^3)-))
  =(-OH)-(-R|^1)=)
}

Atom font

The final thing to adjust to get this example right is the font used for atom labels: the convention is to use sanserif. ChemFig prints text using the \printatom command, which is set up to ensure math mode and \mathrm. Thus the simplest approach is

\renewcommand*{\printatom}[1]{\ensuremath{\mathsf{#1}}

Like many people, I use the excellent mhchem to write in-line chemical equations, so I wanted to use the \ce (or faster \cf) command for printing atoms. My initial attempt failed, with an internal error. A quick e-mail to the ChemFig author led to a fix

\makeatletter
\def\CF@node@content{%
  \expandafter\expandafter\expandafter
    \printatom\expandafter\expandafter\expandafter
      {\csname atom@\number\CF@cnt@atomnumber\endcsname}%
    \ensuremath{\CF@node@strut}%
}
\makeatother

followed by

 \renewcommand*{\printatom}[1]{{\sffamily\cf{#1}}}

leads to the final input

\documentclass{article}
\usepackage{chemfig}
\usepackage[version=3]{mhchem}
\makeatletter
\def\CF@node@content{%
  \expandafter\expandafter\expandafter
    \printatom\expandafter\expandafter\expandafter
      {\csname atom@\number\CF@cnt@atomnumber\endcsname}%
    \ensuremath{\CF@node@strut}%
}
\makeatother
\setdoublesep{0.35700 em}  % 'Bond Spacing'
\setatomsep{1.78500 em}    % 'Fixed Length'
\setbondoffset{0.18265 em} % 'Margin Width'
\newcommand{\bondwidth}{0.06642 em} % 'Line Width'
\setbondstyle{line width = \bondwidth}
\renewcommand*{\printatom}[1]{{\sffamily\cf{#1}}}
\begin{document}
\chemfig{
  *6(-(-R|^2)=-
    (-=^[::-60]N-*6(=(-R|^3)-=(-R|^4)-=(-R|^3)-))
  =(-OH)-(-R|^1)=)
}
\end{document}

and output

I’d say that is pretty good: I’d be happy to use this in a publication (although drawing the kind of structures I do my research with would be a challenge!).

In the final part of this series, I’m going to look at some other things that are needed for chemical structures but which don’t show up in the demo I’ve used. We’ll see that many can be done, but there will be one or two outstanding challenges.

12 thoughts on “Exploring ChemFig: Customising appearance

  1. I’m still not seeing WHY I would ever want to do this much work. If someone makes a GUI for it, or allows me to input a name, or SMILES string or something, then it might be useful…

  2. I like the patch for “mhchem” (I wonder why that never occurred to me…)

    @Canageek: from my experience it is also a matter of practice/routine. Molecules like this one are easy enough and a matter of minutes. Other ones are quite more challenging (a way less comfortable!). 🙂

  3. @Canageek As I said at the start of part one, I’m not about to abandon ChemDraw: I’m trying out ChemFig to see what works and what doesn’t. I’ve wondered what would work as an input format: perhaps parsing .cdxml might work (SMILES or similar is no good as there is no layout information).

  4. @Canageek: a GUI approach usually includes some payment necessary (I haven’t found a free software that produces even near the quality). Nevertheless, as Joseph mentioned, ChemDraw is the tool for research (publication quality, acceptance, etc. and maybe most important: who does not cooperate with non-latex users?!). I am using ChemFig quite extensively for my lecture materials. The code is rather simple to write down… but debugging can be a pain. After a while and with good indentation it gets easier and for larger molecules the definesubmol{}{} command is really helpful.

    @Joseph: Really like the wider bonds in your example. Much more readable on slides than my normal default setatomsep{2em}setcrambond{.25em}{}{}. Any idea how to reduce the “cracks” in bond corners?

  5. @MaBu As you say, none of the free chemical drawing (GUI) packages can match the output of paid-for ChemDraw or ChemDoodle.

    The ‘cracks’ look very tricky to me: I suspect there’s quite a lot of maths in the GUI programs to get this right. Perhaps the author of ChemFig might have an idea: I’ll ask him!

  6. @Joseph: Checked the ChemFig manual and the only other parameter you could tweak is setbondoffset which cannot solve this. So I read in the TikZ manual and found a quick and dirty solution: appending the TikZ option “cap = round” to the bonds closes the gap (the output then looks quite similar to what ChemDoodle produces).

    TkiZ could close the gap automatically, but only if the bonds are defined in one path (with joint=miter with is default). Couldn’t find a way to do something similar to independent lines that intersect at one node.

  7. @Paulo Nothing complicated: I looked up the values in ChemDraw, then used a simple conversion to em.

    @r I use MarvinSketch a look for online searches, but the output would not be any good for publication-quality schemes.

  8. @Joseph, Thank you for these clear explanation which I discover through a link in TexStackExchange. I tried to use the setting and got an error unexpected since I used the same code as your final one except that I used the beamer class and version 4 of mhchem (usepackage[version=4]{mhchem}). I made some tests and it appeared that:
    – with version 3 of mhchem, it runs smoothly with both classes (article and beamer),
    – with version 4 of mhchem, I got errors related to the printatom command.
    After that I had a look at the mhchem documentation and discovered the cf command had been deprecated in version 4.
    So I will have stick to version 3 compatibility mode to run these settings.
    The purpose of this comment is mainly aimed at saving time of people reading this post by informing them of this compatibility trouble with version 4 of mhchem.

Leave a Reply