I am trying to convert handwritten text or handdrawn sketches to TikZ. Usually the thickness of a pen stroke varies when the writer applies more or less pressure to the surface.
I am looking for a short way to map that to TikZ, e.g. this syntax would be awesome:

\draw (1,1) --[2pt] (1,3) --[1pt] (2,3);

To draw a 2pt line from (1,1) to (1,3) and a 1pt line from (1,3) to (2,3).

I know that this:

\draw[line width=2pt] (1,1) -- (1,3);
\draw[line width=2pt] (1,1) -- (1,3);

would work, but it's not very practical for lots and lots of coordinates.

Thanks to Andrew Staceys answer, I was able to finish the tool, which converts handdrawn Xournal sketches to TikZ code.
If you find it useful for your purposes, you can download the tool on https://github.com/flyser/xoj2tikz and read the announcement here.

Have fun :-)

  • Look at Trait with variable thickness
    – Ignasi
    Commented Feb 3, 2012 at 20:20
  • Trait with variable thickness is not exactly what I am looking for, because a decoration can not differentiate between the several points of a path (as far as I know). Commented Feb 3, 2012 at 21:08
  • Is Andrew's answer to Looking for TikZ flourishes and vignettes more useful?
    – Ignasi
    Commented Feb 3, 2012 at 21:16
  • I don't to want to make a custom path look like its handwritten, I want to convert a handwritten path to tikz, so unfortunately no ... Commented Feb 3, 2012 at 21:22
  • My initial thought was to explode the path into components (something I did for Jamie Vicary's knot question), but actually, I think it would be eminently and elegantly possible using to paths. Are all your path segments straight lines? (i'm intrigued by the potential usage of this, would you be willing to share more details of the project?). [Typos etc coutesy of iTiePoh, an all-new iPad application] Commented Feb 4, 2012 at 9:28

2 Answers 2


Here's my first attempt using to paths. The idea is to use the to to break up the path into segments and render each one separately, setting the line width on each one. The problem with this (and I can't see a way around this, but it might not be significant if the line widths don't change too much and the line angles don't change much between segments) is that the path is split into segments which means that they don't join up neatly.

  variable line width/.style={
    every variable line width/.append style={#1},
    to path={%
        \draw[every variable line width/.try,line width=\pgfkeysvalueof{/tikz/thickness}] (\tikztostart) -- (\tikztotarget);
  every variable line width/.style={line cap=round, line join=round},
\draw[variable line width={blue}] (1,1) to[thickness=1cm] (1,3) to[thickness=.5cm] (2,3);

The variable line width key could be specified on the tikzpicture environment as an every draw/.style={variable line width}. To be able to write to[2pt] then one would have to do some funky stuff with the .unknown key handler (where's Ryan Reich when you need him) which would be possible, but I imagine that these are automatically generated and so I would guess that it would be possible to output syntax somewhat like the above - if not, say so and I can adapt the above to suit.

Here's the output of the (the original version of the) above:

TikZ lines with variable width

Update (2012-02-07): Added an every variable line width style which gets added to every inner path. Anything specified as an argument to the variable line width key gets appended to this for the duration of that path.

  • I can't tell you how amazed I am :-) This works like a charm! However, I changed "variable line width" to "vlw" and "thickness" to "t". Additionally I added every path/.style={line cap=round, line join=round} to my tikzpicture environment to work around the path join issue. I was able to achieve an almost perfect match between tikz and xournal with that. Just one little problem: when using \draw[vlw], all other parameters are ignored. I can not say \draw[vlw,blue,opacity=0.5] for example. Any idea how to fix that? The to[2pt] syntax would be cool, but not neccessary :-) Commented Feb 6, 2012 at 20:49
  • @Flyser That's because options specified on a path command (such as \draw) are local to that command and (which is important) reset to defaults at the start. So the inner draw, which is doing the actual drawing, isn't picking up the options specified on the outer one. There are several ways around this; I'll put one in in a moment, but what suits best will depend on how much flexibility you want and how much control you have (or want to have) over shaping the input. Commented Feb 7, 2012 at 9:34
  • There's possibly the simplest way to pass parameters to the subpaths. Would that suffice? I added the line cap and line join as defaults (these could be overridden by suitable options to the variable line width key). Commented Feb 7, 2012 at 9:44
  • This example doesn't work for me. There's a dangling comma at line join=round}, and, after resolving it, I get the error: Paragraph ended before \pgfkeys@addpath was complete.
    – Richard
    Commented Apr 11, 2012 at 16:49
  • @Richard: The problem wasn't the dangling comma, it was the blank line that followed it. Don't know how that snuck in, but I've removed it now so it should compile okay. Commented Apr 11, 2012 at 17:50

TikZ supports \foreach loops, maybe this helps when the lines are created according to a specific pattern. See here, page 504 for further information.

Moreover, \tikzset can save you some typing. It lets you define an own style for using in \draw [mystyle].

\tikzset{lw/.style = {line width=2pt}}
\draw [lw] (1,1) -- (2,2);

But if it really comes to "handdrawn" sketches, you might be better off using a vector graphics program such as Inkscape.

  • thats a good suggestion, I can save some bytes with that, but the real problem is that I need a new \draw for each part of the line. My current implementation creates a document with 2100 lines of code and 162kbyte, while an implementation ignoring line widths gives me 44 lines of code (admittedly very long ones) and 42kbyte for my sample document.
    – Flyser
    Commented Feb 3, 2012 at 15:55

You must log in to answer this question.

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