Friday, December 04, 2009

Drawing beautiful block diagrams in LaTeX

I used to put together the illustrations in my publications with a mixture of Inkscape, CorelDraw and psfrag, but obviously this couldn't continue for a long time without becoming an insult to graphic design.

For my latest writings I am returning to the basics: PSTricks. (I know there are lots of other programs to draw block diagrams, but I didn't find any that allowed enough customization). To avoid starting from zero, I am using the PSTricks Signals and Systems package (pst-sigsys), which is easy to customize if you keep the PSTricks user guide (pdf) at hand.

Here's a simple example:

\documentclass{article}
\usepackage{pst-sigsys}

\pagestyle{empty}

\begin{document}

\begin{figure}[ht]
\centering %
\begin{pspicture}[showgrid=false](0.5,-1.2)(9,1.55)
%--- Define blocks ---
\rput(0.5,0){\rnode{s}{$s[n]$}}
\dotnode[dotstyle=square*,dotscale=0.001](1.7,0){dot}
\psblock(3,.75){H1}{$H_1(z)$}
\psblock(3,-.75){H2}{$H_2(z)$}
\psblock(5.8,.75){B2}{$\hat H_2(z)$}
\psblock(5.8,-.75){B1}{$\hat H_1(z)$}
\pscircleop(7.7,0){ominus}
\rput(9,0){\rnode{e}{$e[n]$}}

%--- Connect blocks ---
\psset{style=Arrow}
\ncline[nodesepA=.15]{-}{s}{dot}
\ncangle[angleA=90,angleB=180]{dot}{H1}
\ncangle[angleA=-90,angleB=180]{dot}{H2}
\ncline{H1}{B2} \naput[npos=.5]{$x_1[n]$}
\ncline{H2}{B1} \naput[npos=.5]{$x_2[n]$}
\ncangle[angleB=90]{B2}{ominus} \naput[npos=.5]{$z_1[n]$}
\ncangle[angleB=-90]{B1}{ominus} \naput[npos=.5]{$z_2[n]$}
\ncline[nodesepB=.15]{ominus}{e}
\end{pspicture}
\end{figure}

\end{document}
which, after some retouching of the .sty file produces this pretty diagram:



Update 6th December 2009: Here's a slightly more complicated diagram, based on the same codes as the above example.

15 comments:

memming said...

beautiful!

Steven said...

Thanks! The best part is I can control all my illustrations with one style sheet.

Sangorrin said...

It looks very professional. But I guess it must be very time-consuming if you wanted to do a more complex graph. I wonder if it would be possible to have a tool that translated inkscape SVG into latex representation :D

Steven said...

@Sangorrin: Inkscape itself is that tool! It allows you to export the SVG directly to PSTricks. On the other hand, if there are multiple illustrations that use common elements (such as blocks in a diagram), I prefer to use PSTricks macros to control their appearance.

Sangorrin said...

About that I think that in Inkscape you can have a template illustration and then instantiate it several times. So if you change the template the rest get updated. Is that what you meant?

Steven said...

Exactly. While for reasonably simple illustrations the whole template-editing can be done straight from PSTricks.

Roy said...

Hey Steven, i'm new to latex and i need to draw block diagrams in latex. i've tried using the ps-sigsys package, but everytime there's this error non-pdf special ignored, how do i fix this prob??

thanks in advance!

Steven said...

Hi Roy, when using PSTricks, you should compile to PostScript first. If that works, you can compile the PostScript into a PDF. Hope that helps.

Denitsa said...

Hello.
First, thanks for the useful information, your diagrams are very pretty.

I encountered a problem, however, and I still can't figure out where it comes from.

I pasted your code and the diagram appeared. The text however wasn't in the boxes but stashed on the left, unreadable. I tried other examples from the same package and so far I'm completely unable to put the text in the boxes. And I kind of need it.
Any ideas where this problem is coming from?

Steven said...

@Denitsa: Sounds like something goes wrong with the psframebox command. Maybe you could try some more basic example with psframebox to see where it goes wrong (you can find a couple in chapter VI of the PSTricks user guide).

Denitsa said...

Hi, Steven.
Thanks for the quick reply.

Well, I tried a dozen of examples and the problem seems to be in the coordinates of the box/text.

For example:
\rnode{N3}{\psframebox{some text}}
produces a box with text inside it, while:
\rput(0,3){\rnode{A}{\psframebox{Node A}}} - produces a box with the text outside it.

And I don't get any errors/warnings at all. It's strange.

Xamuel said...

Very nice :)

One of my advisors in undergrad wanted to put a little graphic in a LaTeX file and ended up programming the whole thing as vector art. 9_9

Beautiful boxes, keep up the good work :)

Anonymous said...

For the solution of the text out of boxes see http://tex.stackexchange.com/questions/21128/missing-text-from-boxes-in-block-diagram-pst-sigsys-pstricks

id said...

You are aware that you don't need the 'figure' environment to include pictures? Normally they are used in combination to make the pictures float and add a caption, but this is not mandatory. To compile single pictures only I recommend to use the standalone class, which is created mainly for this task.

Steven said...

@id: Thanks for the hints. I usually need captions, which is why I include the figure environment.