Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.


Show off your best scientific illustration !

The main purpose of this question is to share beautiful scientific pictures, preferably with an educational aspect.


Your post must contain a nice picture and the associated code. One can post several pictures, but it must be done in different replies. Of course, it must be done with LaTeX & Friends : the post must start with a short sentence to present the language that you chose (TikZ, Asymptote ...) and the main packages that helped you to make the picture. Don't hesitate to add comments.


The satisfaction to share without expecting a reward :)

Ok ... 300 points reputation bounty for the best up-voted post until the 15th of Feb.

Related links

I'll contact Texample.net webmaster to see if he is interested to share the best illustrations, with the participant's agreement of course.

Contest: Show Off Your Skillz in TeX & Friends

share|improve this question
that's easy :p dx.doi.org/10.1007/978-3-642-36763-2_46 –  percusse Feb 5 at 8:43
I'll be glad if Till Tantau himself decide to participate, but that would be a bit unfair ... :) –  Thomas Feb 5 at 8:47
What a wonderful question and answers, this is a true feeding frenzy for my inner geek :) –  Kuba Ober Feb 6 at 15:28
I'm surprised this question wasn't closed already by people like this, on the grounds that it's not a question. Or does that apply only to SO, not to tex.SE? –  Dan Dascalescu Feb 7 at 0:06
@DanDascalescu: Here on TeX.SX the mood is much more laazyyy. Think alone the existence of a tag big-list (click on it). –  Speravir Feb 7 at 0:22

48 Answers 48

This was one was my first tikz drawn picture (from a presentation about entropic depletion forces, https://www.dropbox.com/s/s2y238u8s1yx0ck/Main.pdf ). It shows a line optical tweezer.

line optical tweezer

The code is pretty ugly, but my:


\usetikzlibrary{arrows, decorations.markings, calc, fadings, decorations.pathreplacing, patterns, decorations.pathmorphing, positioning,snakes,backgrounds,shapes,intersections}
\tikzfading[name=fade out, inner color=transparent!0, outer color=transparent!100]



\node(left_knobble_microscope_down) at (-0.5,0.925) {} ;
\node(left_knobble_microscope_up) at (0,2.075) {} ;
\node(right_knobble) at (2.5,1.5) {} ;

\draw[line width=2] (0,0) -- (14,0) -- (14,6) -- (11,6) -- (11,3) -- (5,3) -- (3,5.5) -- (3,8) -- (0,8) -- (0,-0.115);
\draw[line width=2] (8.25,4.35) -- (8.25,3);
\draw[line width=2] (7,3.65) -- (7,3);
\draw[line width=2] (7.5,4.5) -- (7.5,6.25);
\draw[line width=2] (8,4.7) -- (8,6.25);

\node[circle,fill=black,minimum size=3.5](knobble_right) at (right_knobble) {};
\path[draw] (right_knobble) circle (0.75) node [right=0.05em of right_knobble] {\parbox{10em}{Inverses Mikroskop}};

\node(tableau) at (7,6.5) {}    ;

\node[rectangle, fill=black, minimum width=7em] at (tableau) {};
\draw[fill=black] (left_knobble_microscope_down) rectangle (left_knobble_microscope_up);

\node(ccd_cable_down) at (1,8) {} ;
\node(ccd_cable_up) at (2,10) {} ;
\draw[fill=none,line width=2] (ccd_cable_down) rectangle (ccd_cable_up);

\node(ccd_down) at (0.5,10) {} ;
\node(ccd_up) at (2.5,14) {} ;
\draw[fill=black,line width=2] (ccd_down) rectangle (ccd_up) node [above=0.1ex of ccd_up] {\parbox{3em}{CCD-Kamera}};

\node(right1_down) at (12,6) {} ;
\node(right1_up) at (14,13) {} ;
\draw[fill=none,line width=2] (right1_down) rectangle (right1_up);

\node(right2_down) at (9,13) {} ;
\node(right2_up) at (15,16) {} ;
\draw[fill=none,line width=2] (right2_down) rectangle (right2_up);

\fill[fill=black,line width=2] (9,15.5) -- (8.5,15.5) -- (6.5,14) -- (6.5,13.5) -- (9,13.5);

\draw[line width=2] (7,13.5) -- (7,8.5) -- (8.5,8.5) -- (8.5,13.5);

\fill[fill=black,line width=2] (7,8.5) -- (7.25,8) -- (8.25,8) -- (8.5,8.5);

\node[line width=1,ellipse,draw,gray,name path=focus](focus) at (7.75,6.5) {\phantom{...}};
\node[line width=1,ellipse,draw,gray,name path=focus_big](focus_big) at (24,13) {\phantom{\parbox{3cm}{bla\\bla\\bla\\bla\\}}};
\draw[line width=1,gray,draw=none,name path=focus_bla] (focus.east) -- (focus_big.east);
\draw[line width=1,gray,draw=none,name path=focus_blo] (focus.west) -- (focus_big.west);
\path[name intersections={of=focus_bla and focus_big},draw,line width=1, gray](intersection-1)--(focus.east);
\path[name intersections={of=focus_blo and focus},draw,line width=1, gray](intersection-1)--(focus_big.west);

\draw[shift={(8.5,4.5)},rotate=-60,line width=2,black](0, 0) arc (87.5:272.5:0.5 and 0.9);
\draw[rotate around={30:(8.5,4.5)},fill=black,draw,line width=2](8.75,4.5) rectangle (6.45,4.5) {};
\node[rectangle,draw,line width=2] at (20,3.625) {Teleskop};
\draw[fill=black, name path=objektiv] (14,3.075) rectangle (14.5,4.225);
\draw[rotate around={45:(28,1)},fill=black,draw,line width=2] (27,1) rectangle (29,1) node [below left=2.5ex and 0.15em] {\parbox{3em}{Galvanome\-terspiegel}};
\draw[rotate around={-45:(28.375,4)},fill=black,draw,line width=2] (27.375,3.5) rectangle (29.375,3.5);
\fill[red,fill opacity=0.5] (24.2,0.9) -- (27.735,0.9) -- (27.935,1.1) -- (24.2,1.1);
\fill[red,fill opacity=0.5] (27.935,1.1) -- (28.25,3.25) -- (27.5,4) -- (27.735,0.9);
\fill[red,fill opacity=0.5] (27.5,4) -- (22.85,4.25) -- (22.85,3) -- (28.25,3.25);

\fill[red,fill opacity=0.5] (17.15,4.25) -- (14.525,4.125) -- (14.525,3.2) -- (17.15,3);
\fill[red,fill opacity=0.5] (10.885,3.965) -- (8.37,3.85) -- (8.37,3.65) -- (10.885,3.4675);
 \node[rectangle,draw,line width=2] at (20,1) {Nd:YLF-Laser};
\node at (24,9.5) {Deckglas};
\draw[<->,line width=2] (20,11) to (28,11);

    \draw[line width=1] (20,12.25) node[ellipse, minimum height=0.1,minimum width=42.5,draw](down_left) {};
    \draw[line width=1] (20,15.75) node[ellipse, minimum height=0.1,minimum width=42.5,draw](top_left) {};
    \draw[line width=1] (28,12.25) node[ellipse, minimum height=0.1,minimum width=42.5,draw](down_right) {};
    \draw[line width=1] (28,15.75) node[ellipse, minimum height=0.1,minimum width=42.5,draw](top_right) {};
    \draw[line width=1] ($(down_left.10)+(0,-0.05)$)..controls (20,13.75) and (20,14.25)..($(top_left.-10)+(0,0.05)$);
    \draw[line width=1] ($(down_right.10)+(0,-0.05)$)..controls (28,13.75) and (28,14.25)..($(top_right.-10)+(0,0.05)$);
    \draw[line width=1] ($(down_right.170)+(0,-0.05)$)..controls (28,13.75) and (28,14.25)..($(top_right.-170)+(0,0.05)$);
    \draw[line width=1] ($(down_left.170)+(0,-0.05)$)..controls (20,13.75) and (20,14.25)..($(top_left.-170)+(0,0.05)$);

    \node[shade,shading=ball,circle,ball color=blue,minimum size=1.25em] at (23,14)  {};
    \node[shade,shading=ball,circle,ball color=blue,minimum size=1.25em] at (25,14)  {};

\clip ([yshift=1.75pt]down_left.south) -- ([yshift=1.75pt]down_right.south) -- (down_right.-85) -- (down_right.-80) -- (down_right.-75) -- (down_right.-70) -- (down_right.-65) -- (down_right.-60) -- (down_right.-55) -- (down_right.-50) -- (down_right.-45) -- (down_right.-40) -- (down_right.-35) -- (down_right.-30) -- (down_right.-25) -- (down_right.-20) -- (down_right.-15) -- (down_right.-10) -- (down_right.-5) -- (down_right.east) -- (down_right.5) -- (down_right.10) -- ($(down_right.10)+(0,-0.05)$)..controls (28,13.75) and (28,14.25)..($(top_right.-10)+(0,0.05)$) -- (top_right.-10) -- (top_right.-5) -- (top_right.east) -- (top_right.5) -- (top_right.10) -- (top_right.15) -- (top_right.20) -- (top_right.25) -- (top_right.30) -- (top_right.35) -- (top_right.40) -- (top_right.45) -- (top_right.50) -- (top_right.55) -- (top_right.60) -- (top_right.65) -- (top_right.70) -- (top_right.75) -- (top_right.80) -- (top_right.85) -- (top_right.90) -- ([yshift=-1.75pt]top_right.north) -- ([yshift=-1.75pt]top_left.north) -- (top_left.-210) -- (top_left.-205) -- (top_left.-200) -- (top_left.-195) -- (top_left.-190) -- (top_left.-185) -- (top_left.-180) -- (top_left.-175) -- (top_left.west) -- ($(top_left.-170)+(0,0.05)$)..controls (20,14.25) and (20,13.75)..($(down_left.170)+(0,-0.05)$) -- (down_left.-210) -- (down_left.-205) -- (down_left.-200) -- (down_left.-195) -- (down_left.-190) -- (down_left.-185) -- (down_left.-180) -- (down_left.-175) -- (down_left.-170) -- (down_left.-165) -- (down_left.-160) -- (down_left.-155) -- ([yshift=1.75pt]down_left.south);
\draw[draw=none] [postaction={path fading=north,fill=red,opacity=0.8}] (16,14) rectangle (32,17);
\draw[draw=none] [postaction={path fading=south,fill=red,opacity=0.8}] (16,14) rectangle (32,11);

\fill[blue!50!white,fill opacity=0.5] (focus_big.-20) -- (focus_big.-40) -- (focus_big.-140) -- (focus_big.-160);
\draw[line width=1,gray!75!black] ([yshift=1.75pt]down_left.south) to ([yshift=1.75pt]down_right.south);
\draw[line width=1,gray!75!black] ([yshift=1.75pt]top_left.south) to ([yshift=1.75pt]top_right.south);
\draw[line width=1,gray!75!black] ([yshift=-1.75pt]down_left.north) to ([yshift=-1.75pt]down_right.north);
\draw[line width=1,gray!75!black] ([yshift=-1.75pt]top_left.north) to ([yshift=-1.75pt]top_right.north);


share|improve this answer
The beamer presentation that you linked is awesome –  Thomas Feb 6 at 16:02

Lifting of a random Delaunay triangulation to a hyperbolic paraboloid:

  1. The planar delaunay triangulation was generated using C++ and CGAL
  2. The data was visualized using asymptote

enter image description here

Here is the c++ code:

#include <fstream>
#include <sstream>
#include <vector>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/Triangulation_euclidean_traits_2.h>
#include <CGAL/Delaunay_triangulation_2.h>

using namespace CGAL;

typedef Exact_predicates_inexact_constructions_kernel   K;

typedef Delaunay_triangulation_2<K>                       Triangulation;
typedef Triangulation::Edge_iterator                        Edge_iterator;
typedef Triangulation::Point                                  Point;
typedef Triangulation::Vertex_handle                        Vertex;
typedef Triangulation::Face                                 Face;

typedef Creator_uniform_2<double,Point>         Creator;
typedef std::vector<Point>                        Point_set;
typedef std::vector<std::string>            Edges_str;

int main () {
  int numPts = 50;
  Point_set points;

  Random_points_in_disc_2<Point, Creator> randomGen (1.0 );
  cpp0x::copy_n( randomGen, numPts, std::back_inserter(points));

  Triangulation dt;

  int num_of_edges = 0;

  Edges_str edges_str;
  Edge_iterator eit;
  for (eit = dt.finite_edges_begin(); eit != dt.finite_edges_end(); ++eit)
      std::ostringstream strs;
      Triangulation::Face& f = *(eit->first);
      int i = eit->second;
      Vertex vs = f.vertex(f.cw(i));
      Vertex vt = f.vertex(f.ccw(i));
      strs << vs->point().x();
      std::string vsx = strs.str();
      strs << vs->point().y();
      std::string vsy = strs.str();
      strs << vt->point().x();
      std::string vtx = strs.str();
      strs << vt->point().y();
      std::string vty = strs.str();

      std::string curr_edge = "("+vsx+","+vsy+")\n"+"("+vtx+","+vty+")\n";

  std::ofstream out("random-delaunay-of-saddle.dat");
  out << num_of_edges << "\n";
  for (Edges_str::iterator it = edges_str.begin(); it != edges_str.end() ; ++it)
    out << *it;
  return 0;

that produces the random Delaunay triangulation in the plane. The generated file random-delaunay-of-saddle.dat is used by the following asymptote code,

import graph3;

surface operator cast(tube t) {
  return t.s;

real gridWidth=1.5;
pen  gridPen=blue;

real xy_level=-2.1;

real f (pair p){
  real x = p.x;
  real y = p.y;
  return 0.5*(x^2-y^2);

struct Edge {
  pair source; // Source point
  pair target; // Target point

struct Edge3D {
  triple source; // Source point
  triple target; // Target point

// Read 2D points from file
file fin=input("random-delaunay-of-saddle.dat");
int num_of_edges = fin;
Edge[] edges;
pair p1,p2;
for (int i=0; i<num_of_edges; ++i){
  Edge e;
  // Scaling the points, so the surface will be compatible with the non
  // approximated one

Edge3D[] floorEdges,saddleEdges;

for (int i=0 ; i<num_of_edges; ++i){
  pair source=edges[i].source;
  real psx=source.x;
  real psy=source.y;
  pair target=edges[i].target;
  real ptx=target.x;
  real pty=target.y;

  triple Source1=(psx,psy,xy_level);
  triple Target1=(ptx,pty,xy_level);
  Edge3D e1;

  triple Source2=(psx,psy,f((source.x,source.y)));
  triple Target2=(ptx,pty,f((target.x,target.y)));
  Edge3D e2;

for (int i=0; i<num_of_edges; ++i){

real minVal = -2;
real maxVal = -minVal;

surface saddle=surface(f,(minVal,minVal),(maxVal,maxVal),nx=6,Spline);

surface plane=surface(
                      new triple(pair p) {
                        return (p.x,p.y,xy_level);

to generate the image.

share|improve this answer

Newton's rings.

  \begin{tikzpicture}[note/.style={rectangle callout, fill=#1}]
  \foreach \x in {1,2,...,22}{  
     \draw[thick] (0,0) circle ({sqrt(\x)});
  \fill[black!100] (0,0) circle (1);
  \foreach \x in {23,24,...,28}{
    \draw[black!30] (0,0) circle ({sqrt(\x)});
  \node (v1) at (-1.014,-6.5) {\Large $m^\text{th}$ ring};
  \draw[very thick,latex-](v1) -- (-1.014,-0.98);
  \node (v2) at (1.414,-5.8) {\Large $\left(m+1\right)^\text{th}$ ring};
  \draw[very thick,latex-](v2) -- (1.414,-1);
  \draw[very thick,-](1.414,6) -- (1.414,0);
  \draw[very thick,-](-1.414,6) -- (-1.414,0);
  \draw[very thick,latex-latex](-1.414,5.8) -- (1.414,5.8);
  \node at (0,6.1) {\Large $D_{m}$};
  \draw[very thick,latex-latex](4.6904,7.4) -- (-4.6904,7.4);
  \node at (0,7.7) {\Large $D_{m+21}$};
  \node [draw,note=white!100, callout relative pointer={(2.05,-2.8)}] at (-7,3) {\Large Take first
  \node (v3) at (-4.6904,8) {\Large $m+21$};
  \draw[very thick,-](v3) -- (-4.6904,0);
  \node [draw,note=white!100, callout relative pointer={(-2.05,-2.8)}] at (7,3) {\Large Take last
  \node (v4) at (4.6904,8) {\Large $m+21$};
  \draw[very thick,-](v4) -- (4.6904,0);

enter image description here


We have an experiment in optics to measure the focal length of a lens using Newton's ring set up. This diagram is an illustration provided in the manual depicting the rings pattern. The radii of the rings are accurately equal to square root of 1,2,3..... Students take readings for only 21 rings and hence they are made dark for visibility.

share|improve this answer

Prime factorization




\catcode`\_ 11

% This code (non-expandable) produces {{}{}{N}} followed by
% successive braced triplets {{p}{k}{m}} where p is
% a prime factor of N,  k its exponent in N, and m is
% the result of dividing N by p^k and all previous
% powers of smaller primes. So, the last triplet has m = 1.

% The code uses package xint to be able to deal
% with numbers larger than the TeX limit of 2^{31}-1
% on count registers. 


       \expandafter \factorize_ii
       \expandafter \factorize_i

       \expandafter \factorize_iii


       % Here N > 1, N = QM+R (0 < R < M) is < M(Q+1) and N has no
       % prime factors at most equal to M. If a prime P > M divides N, the
       % quotient N/P will be < Q+1, hence at most Q. If Q <= M, then
       % N/P must be 1 else there would be some prime <=M dividing N.
       \if\xintGeq\factorize_M\factorize_Q 1% Implies that N is prime.
          \edef\factors{\factors{{\factorize_N}{1}{1}}}% We stop here.
       \else% We go on testing with bigger factors.
          % \edef\factorize_M{\xintInc{\xintInc{\factorize_M}}}%
          \edef\factorize_M{\xintiAdd \factorize_M 2}%
          \expandafter \expandafter \expandafter \factorize_iii

\catcode`\_ 8

% We now define the macro \FactorTree which will produce
% a tree displaying the factorization.



    \FactorsToTree@ #1%

% Macro which was used to produce the images;
% variant follows which skips the exponents equal to 1.

% \newcommand*\FactorsToTree@[3]{%
%     \xintSgnFork{\xintCmp{#3}{1}}% check to see if end has been reached
%     {}%
%     {\FactorTreeA\expandafter{\the\FactorTreeA
%                               \Tcircle{$\num{#1}^{#2}$}%
%                               \TR{1}%
%                               }}%
%     {\FactorTreeA\expandafter{\the\FactorTreeA 
%                              \Tcircle{$\num{#1}^{#2}$}%
%                              \psTree{\TR{\num{#3}}}}%
%      \FactorTreeB\expandafter{\the\FactorTreeB \endpsTree}}%
% }

% This variant will not print the exponents equal to 1:

    \ifnum 0#2=1 % First triplet has an empty #2, hence the trick with 0.
    % Exponent #2 is 1, so don't print it.
    {\xintSgnFork{\xintCmp{#3}{1}}% Check to see if end has been reached.
     \FactorTreeB\expandafter{\the\FactorTreeB \endpsTree}}}
    % Exponent #2 is > 1 (or absent in the {}{}{N} triplet).
    {\xintSgnFork{\xintCmp{#3}{1}}% Check to see if end has been reached.
     \FactorTreeB\expandafter{\the\FactorTreeB \endpsTree}}}%

\def\@factorinliner #1{\@factorinliner@#1}
  \ifnum #2>1 \expandafter\@firstoftwo\else

    $\num{#1} = \FactorizeInline{#1}$







share|improve this answer

I couldn't bear to let this go without at least one example of a picture produced by mfpic. It is not very flashy, but it illustrates that mfpic has built-in commands to produce figures in the hyperbolic geometry of a disk (for those of us who study function theory in the unit disk.):

Hyperbolic metric disks:

  \setmfpair{Z}{(dir 45)/3}
  \setmfpair{W}{Moebius (Z)(.5*dir -45)}

Hyperbolic geodesics:

      \hypergeodesic{.999*dir 0, .999*dir 120}
      \hypergeodesic{.999*dir 120, .999*dir 240}
      \hypergeodesic{.999*dir 240, .999*dir 0}
    \mfpfor{J=0 upto K-1}
      \rotatepath{(0,0),J*(360/K)}\hypergeodesic{.999*dir 0, .999*dir (360/K)}


Some hyperbolic disks

Hyperbolic geodesics

share|improve this answer

Edit: Oops, realized too late this was about images drawn using latex.

Typing up a conference paper for ICGG 2014 in Innsbruck about phase spaces and fitness landscapes. Although I'm a programmer for a 3D CAD company, I've grown very tired of rendered images as of late. I find it very difficult to draw focus to specific salient details in a digital image.

Although I heavily rely on 3D software and custom programming to generate the geometry in these images, everything is ultimately hand-drawn. Labels are added directly in LaTeX using \put commands, so the images are kept clean.

enter image description here

enter image description here

enter image description here

enter image description here

Not sure what anyone is going to learn from the code, but here is the tex for the bottommost image:

\begin{figure}[H] \centering
 \put (40,15) {\smaller[2] $\nicecirc{1}$}
 \put (66,35) {\smaller[2] $\nicecirc{1}$}
 \put (3,46)  {\smaller[2] $\nicecirc{2}$}
 \put (45,55) {$\pazocal{L}^\prime$}
\caption{Geometry of overconstrainedness}
share|improve this answer
This does not really answer the question, because the question is interested in graphics that were actually created in LaTeX, and not included from image files. Also please post an image of the result of the included code. –  marczellm Feb 11 at 21:49
Very nice pictures. It would be great if we could draw such pictures in LaTeX:-) –  Marc van Dongen Feb 14 at 12:26

Here is a plot of the log barrier function B(x1, x2) = -ln x1 - ln x2.

enter image description here

Code (python to generate the lattice):

from numpy import linspace, pi, sin, cos, log
from scipy.optimize import bisect

# Code to generate patches
# (x(r,theta), y(r,theta), z(r,theta)), where
#    x(r,theta) = 1 - r cos(theta), 
#    y(r,theta) = 1 - r sin(theta), 
#    z(r,theta) = -log(x(r,theta)) - log(y(r,theta)).

PATCH = [(0,0), (2,0), (2,2), (0,2), (1,0), (2,1), (1,2), (0,1), (1,1)]
N     = 23
zmax  = 6
zmin  = -log(1)-log(1)

# Determine the value such that z = -log(x(r,theta)) - log(y(r,theta)).
def zinv(theta, z):
  f = lambda r: -log(1 - r*cos(theta)) - log(1 - r*sin(theta)) - z
  maxr = min(1/cos(theta), 1/sin(theta)) - 1e-6
  return bisect(f, 0, maxr)

P = dict()
V = []

# Generate lattice points
for i, theta in enumerate(linspace(1e-6, pi/2-1e-6, N)):
  for j, z in enumerate(linspace(zmin, zmax, N)):
     r = zinv(theta, z)
     x = 1 - r * cos(theta)
     y = 1 - r * sin(theta)
     z = - log(x) - log(y)
     P[i,j] = len(V)

# Write vertices
vfile = open("logbarrier_v.txt", "wt")
for v in V:
  vfile.write("%0.8f %0.8f %0.8f\n" % v)

# Write patches
pfile = open("logbarrier_p.txt", "wt")
for j in range(0, N-1, 2):
  for i in range(0, N-1, 2):
    for (di, dj) in PATCH:
       pfile.write(str(P[i+di,j+dj]) + " ")

and LaTeX:




\begin{axis}[xmin=0, xmax=1.2, ymin=0, ymax=1.4, zmin=0, zmax=6, 
             axis y line=center, axis x line=center, axis z line=center,
             view/h=70, xtick={0, 1}, ytick={0}, ztick={0,5}, 
             clip=false, axis on top=false, axis line style=thick, every tick/.style={black, thick}]

\node at (rel axis cs:1,0,0) [above, anchor=north west] {$x_1$};  %sloped like x axis, 
\node at (rel axis cs:0,1,0) [above, anchor=west] {$x_2$};
\node at (rel axis cs:0,0,1) [above, anchor=south] {$B(x_1,x_2)$};

\addplot3 [patch,patch type=biquadratic,shader=faceted interp,samples=5,draw=black, draw opacity=0.8,opacity=0.8,z buffer=sort,
   patch table=logbarrier_p.txt,colormap={custom}{color(0)=(plotfill) color(4)=(plotblue)}]
file {logbarrier_v.txt}; 

\addplot3 [patch,patch type=biquadratic,mesh,draw=black, draw opacity=0.05,z buffer=sort,
   patch table=logbarrier_p.txt]
file {logbarrier_v.txt}; 

\draw [dashed] (axis cs: 1, 0, 0) -- (axis cs: 1, 1, 0);
\draw [dashed, opacity=0.33] (axis cs: 1, 1, 0) -- (axis cs: 0, 1, 0);
\draw [dashed, thick, opacity=0.33] (axis cs: 0, 0.2, 0) -- (axis cs: 0, 1.3, 0);
\draw [thick, opacity=0.33] (axis cs: 0, 1, 0.15) -- (axis cs: 0, 1, -0.15);
\node at (axis cs: 0, 1, 0) [anchor=south, opacity=0.33] {$1$};
\node at (axis cs: 0, 0, 0) [anchor=east] {$\mathbf{0}$};

share|improve this answer
BTW: For anyone interested, I just learned that you can enable syntax highlighting to non-LaTeX code on stackexchange by adding e.g. <!-- language: lang-python --> in front of python code (see my post). –  Yori Feb 18 at 8:48


This diagram shows a decimation process in a database. The first level shows random samples, and subsequent levels calculate the min, mean, and max of groups of four entries from each previous level.

The cool thing about this is that all of the math, including the random number generation, is done directly in TikZ. Since the actual numbers didn't matter, I was able to choose a random seed that made the result look best.



%\toggletrue{quickdecim} % Uncomment this to render more quickly (non-random)


  \def\levels{4} % 2, 3, or 4

  \definecolor{lowcolor} {rgb}{0.6,0.6,1}

  \tikzstyle{Sample} = [
  draw, anchor=west,
  inner sep=0,
  outer sep=0,
  minimum height=\sampleheight * 1cm,

  % make random numbers
  \foreach \x[count=\xi from 1] in {2,...,\blocks}{

  % boxes
  \foreach \level in {1,...,\levels} {
    \coordinate (level\level sample0) at
    (\xoffset - \totalwidth / 2,
    \yoffset + \levelheight - \levelheight * \level);
    \pgfmathsetmacro{\levelblocks}{\blocks / \avgblocks}

    \foreach \i in {1,...,\levelblocks} {
        % can do this instead of using real samples, for speed
        % calculate sample values from the randarray
        \pgfmathsetmacro{\countfrom}{(\i - 1) * \avgblocks}
        \pgfmathsetmacro{\countto}{\countfrom + \avgblocks - 1}
        \foreach \j in {\countfrom,...,\countto} {
          \pgfmathsetmacro{\tmp}{\samplesum + \randarray[\j] / \avgblocks}
          \pgfmathtruncatemacro{\tmp}{min(\smin, \randarray[\j])}
          \pgfmathtruncatemacro{\tmp}{max(\smax, \randarray[\j])}
      \pgfmathtruncatemacro{\cmin}{(\smin - 1) / (\maxrand - 1) * 100}
      \pgfmathtruncatemacro{\cmean}{(\smean - 1) / (\maxrand - 1) * 100}
      \pgfmathtruncatemacro{\cmax}{(\smax - 1) / (\maxrand - 1) * 100}

        \node[Sample, xshift=\samplewidth * \prev cm, draw,
        yshift=\sampleheight * -2cm,
        minimum width=\samplewidth cm,
        (level\level samplemax\i) at (level\level sample0) {};
        \coordinate (level\level samplemin\i) at (level\level samplemax\i);
        \coordinate (level\level samplemean\i) at (level\level samplemax\i);
        \node[Sample, xshift=\samplewidth * \prev cm, draw,
        yshift=\sampleheight * 0cm,
        minimum width=\samplewidth cm,
        (level\level samplemin\i) at (level\level sample0) {\smin};

        \node[Sample, xshift=\samplewidth * \prev cm, draw,
        yshift=\sampleheight * -1cm,
        minimum width=\samplewidth cm,
        (level\level samplemean\i) at (level\level sample0) {\smean};

        \node[Sample, xshift=\samplewidth * \prev cm, draw,
        yshift=\sampleheight * -2cm,
        minimum width=\samplewidth cm,
        (level\level samplemax\i) at (level\level sample0) {\smax};

    \coordinate (level\level sampleminlabel)
    at (level\level samplemin\levelblocks);
    \coordinate (level\level samplemeanlabel)
    at (level\level samplemean\levelblocks);
    \coordinate (level\level samplemaxlabel)
    at (level\level samplemax\levelblocks);

  % arrows
  \foreach \next in {2,...,\levels} {
    \pgfmathsetmacro{\amplitude}{3pt * \level + 1.5pt}
    \pgfmathsetmacro{\thislevelblocks}{\blocks / (4^(\level-1))}
    \pgfmathsetmacro{\nextlevelblocks}{\blocks / (4^(\level))}
    \foreach \block in {1,...,\nextlevelblocks} {
      \draw [thick, decorate, decoration={brace, amplitude=\amplitude, mirror}]
      ([xshift=0.5pt]level\level samplemax\a.south west) --
      ([xshift=-0.5pt]level\level samplemax\b.south east);
      \draw[thick, -stealth]
      ([yshift=-\amplitude]level\level samplemax\c.south east) --
      (level\next samplemin\block .north);

  % text
  \foreach \level in {1,...,\levels} {
    \pgfmathtruncatemacro{\decim}{(4^(\level - 1))}
    % Level N
    \node[xshift=-2.5cm, yshift=6pt, anchor=west] (foo) at
    ($(level\level sample0 |- level\level samplemean1)$)
    {Level \level};
    % Samples
    \node[anchor=north, inner sep=0, font=\footnotesize] at (foo.south)
    {\ifnumequal{\level}{1}{(${\color{red}N}$ values)}
      {($3\cdot {\color{red}N / \decim}$ values)}};

  \begin{scope}[anchor=west, inner sep=0, font=\footnotesize\itshape,
    text depth=0ex, text height=1.1ex, draw]
    \foreach \level in {2,...,\levels} {
      \node[xshift=3pt] at (level\level sampleminlabel) { min };
      \node[xshift=3pt] at (level\level samplemeanlabel) { mean };
      \node[xshift=3pt] at (level\level samplemaxlabel) { max };

  \node[yshift=-0.8cm] at (foo.south) { $\vdots$ };


share|improve this answer

Not very scientific and clearly not that awesome as the rest from here, but it was a big deal for me since a knew nothing about TikZ (I still know nothing, though :P). It's the ATDD cycle.

enter image description here

The code it's not pretty.





\tikzset{normalstyle/.style={draw, drop shadow, fill=white, rectangle, inner sep=5pt, font=\bfseries, align=center}}
\tikzset{bubble/.style={draw, circle, fill=white, minimum width=5em}}
\def \radius {0.30\textwidth}

\def \offset{-5} % para que la linea que une rojo con verde sea diagonal

    \draw[dotted, thick] ({90 + \offset - 1}:\radius*1.4) -- ({-90 + \offset -1 }:\radius*1.4);

    \path[name path=circulo] (0, 0) circle (\radius);

    \node(elegir_us)[normalstyle, name path=path_elegir_us] at ({-173 + \offset}:\radius) {Elegir\\ User Story};

    % START
    \node (start) [node distance=0mm and 8mm, left=of elegir_us, circle, fill=black, minimum width=1pt]{};

    \node(escribir_pruebas)[normalstyle,name path=path_escribir_pruebas] at ({164 + \offset}:\radius) {Escribir pruebas\\ de aceptacion\\ para la Story};

    \node(implementar_prueba)[normalstyle, name path=path_implementar_prueba] at ({132 + \offset}:\radius) {Implementar\\ prueba de\\    aceptacion};

    \node(prueba_fallando)[name path=path_prueba_fallando,draw, drop shadow, fill=red, rectangle, inner sep=5pt, font=\bfseries, align=center] at ({90 + \offset}:\radius) {Prueba de\\ aceptacion\\ fallando};

    \node(prueba1)[bubble,name path=path_prueba1] at ({52 + \offset}:\radius){Prueba};
    \node(codigo1) [bubble, above right = 1mm and 5mm of prueba1.center] {Código};
    \node(refactor1) [bubble,name path=path_refactor1, below right = 1mm and 5mm of prueba1.center] {Refactor};

    \node(prueba2)[bubble,name path=path_prueba2] at ({0 + \offset}:\radius){Prueba};
    \node(codigo2) [bubble, above right = 1mm and 5mm of prueba2.center] {Código};
    \node(refactor2) [bubble, below right = 1mm and 5mm of prueba2.center] {Refactor};    

    \node(prueba3)[bubble,name path=path_prueba3] at ({-52 + \offset}:\radius){Prueba};
    \node(codigo3) [bubble,,name path=path_codigo3, above right = 1mm and 5mm of prueba3.center] {Código};
    \node(refactor3) [bubble, below right = 1mm and 5mm of prueba3.center] {Refactor};    

    \node(prueba_pasando)[name path=path_prueba_pasando, draw, drop shadow, fill=green, rectangle, inner sep=5pt, font=\bfseries, align=center] at ({-90 + \offset}:\radius) {Prueba de\\ aceptacion\\ pasando};

    \node(refactor)[normalstyle, name path=path_refactorizar] at ({-128 + \offset}:\radius) {Refactorizar};

    \node(aceptacion_cliente)[normalstyle, name path=path_aceptacion_cliente] at ({-149 + \offset}:\radius) {Aceptacion\\ Cliente};


    \path [name intersections={of=circulo and path_elegir_us,name=intELEGIRUS}];

    \path [name intersections={of=circulo and path_escribir_pruebas,name=intESCRIBIRPRUEBAS}];

    \path [name intersections={of=circulo and path_implementar_prueba,name=intIMPLEMENTARPRUEBA}];

    \path [name intersections={of=circulo and path_prueba_fallando,name=intPRUEBAFALLANDO}];

    \path [name intersections={of=circulo and path_prueba1,name=intPRUEBAUNO}];

    \path [name intersections={of=circulo and path_refactor1,name=intREFACTORUNO}];

    \path [name intersections={of=circulo and path_prueba2,name=intPRUEBADOS}];

    \path [name intersections={of=circulo and path_codigo3,name=intCODIGOTRES}];

    \path [name intersections={of=circulo and path_prueba3,name=intPRUEBA3}];

    \path [name intersections={of=circulo and path_prueba_pasando,name=intPRUEBAPASANDO}];

    \path [name intersections={of=circulo and path_refactorizar,name=intREFACTORIZAR}];

    \path [name intersections={of=circulo and path_aceptacion_cliente,name=intACEPTACIONCLIENTE}];

    \draw [->,bend left=15] (node cs:name=start, anchor=east) to (node cs:name=elegir_us, anchor=west);
    \draw [->,bend left=15] (\ELEGIRUSUP) to (\ESCRIBIRPRUEBASDOWN);
    \draw [->,bend left=15] (\ESCRIBIRPRUEBASUP) to (\IMPLEMENTARPRUEBADOWN);
    \draw [->,bend left=15] (\IMPLEMENTARPRUEBAUP) to (\PRUEBAFALLANDOLEFT);
    \draw [->,bend left=15] (\PRUEBAFALLANDORIGHT) to (\TRIBUBBLEUNOUP);
    \draw [->,bend left=15] (\TRIBUBBLEUNODOWN) to (\TRIBUBBLEDOSUP);
    \draw [->,bend left=15] (\TRIBUBBLEDOSDOWN) to (\TRIBUBBLETRESUP);
    \draw [->,bend left=15] (\TRIBUBBLETRESDOWN) to (\PRUEBAPASANDORIGHT);
    \draw [->,bend left=15] (\PRUEBAPASANDOLEFT) to (\REFACTORIZARDOWN);
    \draw [->,bend left=15] (\REFACTORIZARUP) to (\ACEPTACIONCLIENTEDOWN);
    \draw [->,bend left=15] (\ACEPTACIONCLIENTEUP) to (\ELEGIRUSDOWN);

    % TDD Y ATDD
    \node [above left = 10mm and 10mm of prueba_fallando.center, font=\Large\bfseries] {ATDD};
    \node [above right = 10mm and 10mm of prueba_fallando.center, font=\Large\bfseries] {TDD};

share|improve this answer

Configuration Space and Symbolic Subspace of a 2-Degrees of Freedom Robot

Depending on its configuration, it can either be in the symbolic state of penetrating the wall, or not penetrating it.

Configuration Space and Symbolic Subspace of a Simple Robot


  \tikzstyle{block} = [draw, color=\ColSymBorder, ultra thick, fill=\ColSymFill, rectangle,  minimum height=3em, minimum width=6em];
  \draw[color=\ColSymBorderTwo, ultra thick, fill=\ColSymFillTwo] (0,0) rectangle (4,4);
  \draw (0,0) node[below,left]{$0^\circ$} -- (4,0) node[below,midway] {$\theta_1$} node[below,right] {$180^\circ$};
  \draw (0,0) -- (0,4) node[left,midway] {$\theta_2$} node[left] {$180^\circ$};


  \draw[ultra thick,color=\ColSymBorder,fill=\ColSymFill, rounded corners=3pt] 
                   (0,0.2) .. controls (0,1) and (0,2) ..   (0,3.8)
                         .. controls (0.3,3.5) and (0.8,3.1) .. (1,2.6)
                         .. controls (1.4,2.0) and (1.6,1.2) .. (2,0)
                         .. controls (1,0) and (0.5,0) .. (0.3,0)
                         .. controls (0.2,0.1) and (0.1,0.2) .. (0,0.3);
                         %.. controls (3,0) and (2,0) .. (0,0);

  \foreach \x in {1,100,...,180}{
   \foreach \y in {1,100,...,180}{
     %\ifthenelse{ {cos(\x)*40+50/cos(90-(\x+\y))} < 50}
     %\ifthenelse{ \lengthtest{ {\f{\x}} pt < 50 pt}}

       \pgfmathparse{ (
       (cos(\x)*40pt+sin(\x+\y)*50pt)<(\wallOffset+\marginOff)) &&
       (cos(\x)*40pt+sin(\x+\y)*50pt)>(\wallOffset-\marginOff))) ?1:0}
          %penetrates the wall
          %out of the wall


  \draw[thick,color=\ColSymBorder] (-2,1) -- (0,1);
  \node[block] at (-3,1) {$s_0: $ penetratesWall};
  \draw[thick,color=\ColSymBorderTwo] (6,3) -- (4,3);
  \node[draw, color=\ColSymBorderTwo, ultra thick, fill=\ColSymFillTwo, rectangle,
  minimum height=3em, minimum width=6em] at (7,3) {$s_1: \neg$penetratesWall};


    \pgfmathsetlengthmacro{\rone}{40pt} %length link1
    \pgfmathsetlengthmacro{\rtwo}{50pt} %length link2
    \pgfmathsetlengthmacro{\rw}{10} %width of base rectangle
    \pgfmathsetlengthmacro{\thetaone}{#1} %angle base-link1
    \pgfmathsetlengthmacro{\thetatwo}{#2} %angle link1-link2
    \coordinate (base) at (#3,#4); %base coordinates

    %\coordinage (cspace) at ({#1/180*\endDom},{#2/180*\endDom})

    \path (base);
    \draw[thick,color=black] ({\xbase+1cm},{\ybase+3.0cm}) -- ({#1/180*\endDom},{#2/180*\endDom});
    \draw[fill=black] ({#1/180*\endDom},{#2/180*\endDom}) circle (2pt);

    \draw[thick,color=black] ({\xbase-1cm},{\ybase-0.5cm}) rectangle

    \draw[fill=\wallColor] ({\xbase+\wallOffset}, {\ybase-0.5cm}) rectangle
    ({\xbase+3cm}, {\ybase+3cm});

    \coordinate (t1) at (\tx,\ty);

    \coordinate (t2) at (\sx,\sy);
    \draw[ultra thick,black] (base) -- (t1);% node[below] {$\tx \ybase \xbase \ty$};
    \draw[ultra thick,black] (t1) -- (t2);% node[below] {$\tx \ybase \xbase \ty$};

    \draw[thick,color=black,fill=white!30] ({\xbase-0.5*\rw},{\ybase-0.5*\rw}) rectangle++ (\rw,\rw);
    \draw[thick,color=black,fill=white!10] (t1) circle (2pt);
    \draw[thick,color=black,fill=white!10] (t2) circle (2pt);

    %% dashed line to represent link two at 0 degree
    \pgfmathsetlengthmacro{\rtmp}{\rone }
    \coordinate (tmp1) at (\tmpx,\tmpy);
    \draw[dashed,color=black] (t1) -- (tmp1);

    %% dashed line to represent link one at 0 degree
    \coordinate (tmp0) at (\tmpx,\tmpy);
    \draw[dashed,color=black] (base) -- (tmp0);


    \coordinate (tmp0t) at (\tmpx,\tmpy);

    \coordinate (tmp1t) at (\tmpx,\tmpy);

    % ($(O)+(\StartAngle:-\Radius)$) is the center of the yellow circle

    \draw[bend right,thick,->]  (tmp1) to node [auto] {$\theta_2$} (tmp1t);
    \draw[bend right,thick,->]  (tmp0) to node [auto] {$\theta_1$} (tmp0t);


share|improve this answer

Mexican Hat potential

Spontaneous Symmetry Breaking illustrated for a "mexican hat" potential.

Asymptote code:

import graph3;



real f(pair z) {return -abs(z)^2+0.5*abs(z)^4;}

bbox3 b=limits(O,1.75(1,1,1));

picture surface=surface(f,(-1.3,-1.3),(1,1),nx=100,palegray);

share|improve this answer

Here are two example figures produced with the Pre-/Postprocessor gmsh. gmsh has the capability to export geometries, meshes and post processing views (e.g. result of a finite element simulation) to LaTeX using pgfplots. The key feature is that axes, color map and orientation data are automatically exported. It works nicely for three-dimensional views, by automatically creating the mapping of world coordinates (x,y,z) to pixel coordinates (X,Y).

The image in the figures is still a png with a transparent layer, but the axes/labels/captions/annotations are all done with pgfplots.

Disclosure: I added this functionality myself. More info/demos.

View on a mesh of a ring shaped pipe.

Three quarters of a ring shaped pipe

    width=.5\linewidth, % set figure width here
    enlargelimits=false, % tight axis, use xmin=<val>, xmax=<val> for custom bounding box
    minor tick num=1,
    3d box,
    xlabel={x}, %
    zlabel style={rotate=90},
      \addplot3[surf] graphics[debug=false,%=visual,
        (-12,-2,-12) => (750,595-341)
        (-12,8,-12) => (743,595-23)
        (-12,8,12) => (16,595-98)
        (12,-2,-12) => (1039,595-520)
        (12,-2,12)%  => (308,595-595)
        (12,8,-12)%  => (1038,595-202)
        (12,8,12)%  => (306,595-277)
        (-12,-2,12)%  => (18,595-415)

Example of a post processing view with automatically exported axes and color bar.

The dashed line and the dummy legend was added manually to demonstrate that drawing on top of the figure is easy. Everything else was created automatically.

Post processing view

colormap={gmshcolormap}{% note: Only needed once if colorbars do not change
rgb255=(0,12,92) rgb255=(0,7,98) rgb255=(9,3,103) rgb255=(19,0,107) rgb255=(30,0,110) rgb255=(40,0,112) rgb255=(50,0,113) rgb255=(60,0,114) rgb255=(70,0,114) rgb255=(79,0,114) rgb255=(88,0,113) rgb255=(97,0,111) rgb255=(105,1,109) rgb255=(114,4,107) rgb255=(122,8,104) rgb255=(130,12,100) rgb255=(137,16,97) rgb255=(145,21,93) rgb255=(152,26,88) rgb255=(159,31,84) rgb255=(166,37,79) rgb255=(174,45,73) rgb255=(180,51,68) rgb255=(186,58,63) rgb255=(192,65,58) rgb255=(198,72,53) rgb255=(203,80,48) rgb255=(208,87,43) rgb255=(213,95,38) rgb255=(218,102,33) rgb255=(222,110,29) rgb255=(226,118,25) rgb255=(230,126,21) rgb255=(234,133,17) rgb255=(237,141,14) rgb255=(241,149,11) rgb255=(244,157,9) rgb255=(246,164,7) rgb255=(249,172,6) rgb255=(251,179,5) rgb255=(254,186,5) rgb255=(255,193,5) rgb255=(255,202,7) rgb255=(255,208,9) rgb255=(255,214,11) rgb255=(255,220,15) rgb255=(255,226,19) rgb255=(255,231,25) rgb255=(255,236,31) rgb255=(255,240,38) rgb255=(255,244,46) rgb255=(255,248,55) rgb255=(255,251,66) rgb255=(255,254,77) rgb255=(255,255,90) rgb255=(255,255,103) rgb255=(255,255,118) rgb255=(255,255,134) rgb255=(254,255,152) rgb255=(252,255,171) rgb255=(249,255,191) rgb255=(247,254,213) rgb255=(244,251,236) rgb255=(241,247,255) }
    width=.5\linewidth, % set figure width here
    enlargelimits=false, % tight axis, use xmin=<val>, xmax=<val> for custom bounding box
    xlabel={x}, % if you rotated your view, adjust these labels!
    scale only axis,
    axis equal image, % use png aspect ratio
    axis on top,
    title={Electric Field Intensity / (V/m)},
    scaled ticks=false,
    colormap name=gmshcolormap,
    colorbar right, %or left...
    colorbar style={
            %width=0.5cm, % adjust width of colorbar
            %height=6cm,% adjust height of colorbar,
      % a dummy plot for the colorbar (invisible):
      \addplot[point meta min=0.000000, point meta max=359, update limits=false, 
            draw=none, colorbar source, forget plot]
      \addplot[surf,point meta min=0, point meta max=359] 
            graphics[xmin=0, xmax=0.05, ymin=0, ymax=0.05]
      \addlegendentry{foo $\Phi_x^2$}
      \addplot[black,densely dashed,ultra thick,
         update limits=false,domain=0:0.05,samples=100] {-0.5*x+0.025+0.01*sin(10000*x)};
      \addlegendentry{bar $|\langle \varphi \rangle^2|_\infty$}
share|improve this answer

It appears that I got the wrong end of the stick with this thread, as my images weren't created in LaTeX (I didn't realise that you could do this).

I've tried to rectify this by seeing if I could convert one of my original images to a LaTeX format from the original .eps files using Latexdraw; however, it turns out that my code is quite long (>0.5 M characters). So far I've only tried this for the nuclide map figure. Unfortunately, Latexdraw doesn't seem to be able to handle the original text very well, and I haven't figured out how to do it myself yet.

Anyway, here's a link to the code for the nuclide map if people want to play around with it. If someone does manage to put the text back, I'd be interested to know how you did it and with what software. For the time being I think I'll stick with SerifDraw and Inkscape to draw and convert my images from .svg to .eps, whilst I'm writing up my thesis, but may look to this for future work.

enter image description here

share|improve this answer
I really like both images, but the cool thing would be to make them in LaTeX (and Friends). –  Manuel Feb 7 at 12:26
This is not a proper answer to the question because the illustrations themselves were not created with LaTeX/PGF/TikZ/Asymptote/Metapost/PSTricks. –  marczellm Feb 7 at 12:45

The butterfly curve.



                % x=(sin t)(exp(cos t)-2 cos 4t + (sin(t/12))^5)
                % y=(cos t)(exp(cos t)-2 cos 4t + (sin(t/12))^5)


     \left(\mathrm{e}^{\cos t}-2\cos 4t+\sin^5 \frac{t}{12}\right)
     (\sin t,\cos t)


The butterfly curve

share|improve this answer

Galvanic cell


  figureposition = bottom


  font = small,
  labelfont = sc,
  labelsep = adjustment



  \def\basinWidth{#2 }
  \def\basinHeight{#3 }
% Basin
  \psline(1,0)(!\basinWidth 1 sub 0)
  \psarc(!\basinWidth 1 sub 1){1}{270}{360}
% Membrane
](!\basinWidth 2 div 0)%
 (!\basinWidth 2 div \waterHeight)
% Cathode
](!\basinWidth 4 div 1 sub 1)%
 (!\basinWidth 4 div 1 sub \basinHeight 1 sub)%
 (!\basinWidth 4 div 1 add \basinHeight 1 sub)%
 (!\basinWidth 4 div 1 add 1)
\rput(!\basinWidth 4 div \basinHeight 2 div){\cathode\xspace}
% Anode
](!3 \basinWidth mul 4 div 1 sub 1)%
 (!3 \basinWidth mul 4 div 1 sub \basinHeight 1 sub)%
 (!3 \basinWidth mul 4 div 1 add \basinHeight 1 sub)%
 (!3 \basinWidth mul 4 div 1 add 1)
\rput(!3 \basinWidth mul 4 div \basinHeight 2 div){\anode}
% Wires with current
\rput(!\basinWidth 4 div 1 add \basinHeight){$+$}
\psline(!\basinWidth 4 div \basinHeight 1 sub)%
       (!\basinWidth 4 div \basinHeight)
\psarc(!\basinWidth 4 div 1 add \basinHeight){1}{90}{180}
\psline(!\basinWidth 4 div 1 add \basinHeight 1 add)%
       (!\basinWidth 1 sub 2 div \basinHeight 1 add)
\pscircle(!\basinWidth 2 div \basinHeight 1 add){0.5}
\rput(!\basinWidth 2 div \basinHeight 1 add){$U$}
\psline(!3 \basinWidth mul 4 div 1 sub \basinHeight 1 add)%
       (!\basinWidth 1 add 2 div \basinHeight 1 add)
\psarc(!3 \basinWidth mul 4 div 1 sub \basinHeight){1}{0}{90}
\psline(!3 \basinWidth mul 4 div \basinHeight 1 sub)%
       (!3 \basinWidth mul 4 div \basinHeight)
\rput(!3 \basinWidth mul 4 div 1 sub \basinHeight){$-$}
% Electron movement
\rput(!3 \basinWidth mul 1 add 8 div \basinHeight 3 2 div add)%
\rput(!5 \basinWidth mul 2 sub 8 div \basinHeight 3 2 div add)%

\psset{unit = 0.5\psunit}


% Without optional arguments; the `stardard' version.
 \caption{Galvanic cell where \anode{} is the anode and \cathode{} is the cathode.}

% With optional arguments; a `non-stardard' version.
      anode = Cu,
      anodeColour = red!50,
      cathode = Ag,
      cathodeColour = gray!20
 \caption{Galvanic cell where \ch{Cu} is the anode and \ch{Ag} is the cathode.}



share|improve this answer

Radioactive dacay

Note: There is a screenshot of only the first half life of a nucleus but there are five half lifes for each version (but it can very easily be changed).

First version


  hmargin = 2.4cm,
  vmargin = 3cm
  locale = DE

%%% Constants %%%

  \cs_new_eq:NN \calc \fp_eval:n


%%% Definitions %%%

    fillstyle = solid,
    fillcolor = yellow,
    linestyle = none
    linecolor = yellow
    linecolor = SeaGreen

    \multido{\iA = 0+1, \rC = 0.25+2}{\Halveringer}{%
      \multido{\rA = \rC+0.5}{4}{%
        \multido{\rB = 0.27+0.635}{\konstC}{%
    \multido{\iA = 0+1, \rC = 0.25+2}{\Halveringer}{%
      \multido{\rA = \rC+0.5}{4}{%
        \multido{\rB = 9.795+-0.635}{\konstD}{%
    \multido{\iA = 0+1}{\Halveringer}{%
      \psline(!2   \iA\space mul     \konstA)%
             (!2 1 \iA\space add mul \konstA)%
             (!2 2 \iA\space mul add \konstA\space 2 div)%
    \psline(!2 \Halveringer\space mul 10 \konstB\space mul)%
           (!2 \Halveringer\space mul 0)
      ticks = none,
      labels = none,
      arrowinset = 0.05,
      arrowscale = 1.6,
      arrowlength = 1.8
    ]{->}(0,0)(-0.3,-0.3)(\konstF,10.5)[$t$,0][Radioactive nuclei~(\si{\percent}),90]
      linecolor = red,
      linewidth = 1.5pt
    \multido{\iA = 4+2, \iB = 2+1}{\HalveringerA}{%
      \psxTick(\iA){\iB \cdot T_{\sfrac{1}{2}}}%
    \multido{\iA = 0+1}{\HalveringerB}{%

  \ifnum \totvalue{page} > 1 \relax


% \centering
%  \begin{pspicture}(-2.4,-1.4)(2.4,2.9)
%    \pspolygon[
%      fillstyle = solid,
%      fillcolor = yellow,
%      linewidth = 5\pslinewidth
%    ](2.875;-30)(2.875;90)(2.875;210)
%    \pswedge*(0,0){1.25}{0}{60}
%    \pswedge*(0,0){1.25}{120}{180}
%    \pswedge*(0,0){1.25}{240}{300}
%    \pscircle*[
%      linecolor = yellow
%    ](0,0){0.375}
%    \pscircle*(0,0){0.25}
%  \end{pspicture}
% \centering
%  \begin{pspicture}(-1.8,-1.9)(1.8,1.9)
%    \psframe[
%      fillstyle = solid,
%      fillcolor = yellow,
%      linecolor = gray
%    ](-2,-2)(2,2)
%    \pswedge*(0,0){1.75}{0}{60}
%    \pswedge*(0,0){1.75}{120}{180}
%    \pswedge*(0,0){1.75}{240}{300}
%    \pscircle*[
%      linecolor = yellow
%    ](0,0){0.5}
%    \pscircle*(0,0){0.35}
%  \end{pspicture}

\multido{\iK = 1+1}{5}{%



Second version


  hmargin = 2.4cm,
  vmargin = 3cm
  locale = DE

%%% Constants %%%

  \cs_new_eq:NN \calc \fp_eval:n



%%% Definitions %%%

      fillstyle = solid,
      fillcolor = yellow,
      linestyle = none
      linecolor = yellow

    linecolor = SeaGreen

\def\henfald{rand 301 mod 50 div round 50 div }
\def\simpel#1{!#1 \henfald add \henfald \i\space 5 mul 16 div add 0.121 add }

      linestyle = none,
      fillstyle = gradient,
      gradangle = 45,
      gradmidpoint = 1,
      gradbegin = gray!80,
      gradend = gray!30
    \multido{\i = 0+1}{\halveringerC}{%
        dimen = middel,
        linecolor = NavyBlue,
        linewidth = 1pt,
        fillstyle = gradient,
        gradangle = 90,
        gradmidpoint = 1,
        gradbegin = NavyBlue!50,
        gradend = white
      ](\konstA,0)(!\konstA 1 add \maerkerYa)%
        dimen = middel,
        linecolor = NavyBlue,
        linewidth = 1pt,
        fillstyle = gradient,
        gradangle = 90,
        gradmidpoint = 0,
        gradbegin = SeaGreen!30,
        gradend = white
      ](\konstA,10)(!\konstA 1 add \maerkerYa)%
    \multido{\i = 0+1}{\halveringerC}{%
        \multido{\i = 0+1}{\konstB}{%
          \rput{!\henfald 777 mul}(\simpel{0.125}){\radioaktivt}
          \rput{!\henfald 777 mul}(\simpel{0.375}){\radioaktivt}
          \rput{!\henfald 777 mul}(\simpel{0.625}){\radioaktivt}
          \rput{!\henfald 777 mul}(\simpel{0.875}){\radioaktivt}%
        \multido{\i = 0+1}{\konstC}{%
       ticks = none,
       labels = none,
       arrowinset = 0.05,
       arrowscale = 1.6,
       arrowlength = 1.8
    ]{->}(0,0)(-0.3,-0.3)(\konstD,10.75)[$t$,0][Radioactive nuclei~(\si{\percent}),90]
      linecolor = red,
      linewidth = 1.5pt
      \multido{\i = 2+1}{\halveringerB}{%
        \psxTick(\maerkerX){\i \cdot T_{\sfrac{1}{2}}}%
      \multido{\i = 0+1}{\halveringerC}{%

  \ifnum \totvalue{page} > 1 \relax


\multido{\iK = 0+1}{6}{%



P.S. The macro names are is Danish but I hope it is understandable none the less.

share|improve this answer

I don't know the name of this illusion but the important thing is that it is about simple harmonic motion of equally-spaced points with equally-spaced phase difference. Enjoy! The same code was posted here.

enter image description here



% static point
% #1 : half of the number of points
% #2 : ith point

% oscillated point
% #1 : half of the number of points
% #2 : ith point
% #3 : time parameter

% single frame
% #1 : half of the number of points
% #2 : time parameter
    \pstVerb{/I2P {AlgParser cvx exec} bind def}%
    \foreach \i in {1,...,#1}{\psline[linecolor=yellow](!\x[#1,\i] I2P \y[#1,\i] I2P)(!\x[#1,\i] I2P neg \y[#1,\i] I2P neg)}
    \foreach \i in {1,...,#1}{\pscircle*[linecolor=white](!\X[#1,\i]{#2} I2P \Y[#1,\i]{#2} I2P){2pt}}   

\foreach \t in {0,...,24}
    \Frame{1}{2*Pi*\t/25} \quad \Frame{2}{2*Pi*\t/25} \quad \Frame{3}{2*Pi*\t/25} \quad \Frame{5}{2*Pi*\t/25} \quad \Frame{10}{2*Pi*\t/25}
share|improve this answer

Below I made a basic diagram to illustrate (vertical) interlinkages such as in a supply chain in an economy.

\draw (0,0) -- (6,0);
\draw (0,0) -- (0,-1); \draw (6,0) -- (6,-1);
\draw (0,0) rectangle (1,-1);
\draw (1,0) rectangle (2,-1);
\draw (2,0) rectangle (3,-1);
\draw (3,0) rectangle (4,-1);
\draw (4,0) rectangle (5,-1);
\draw (5,0) rectangle (6,-1);
\draw [yellow, line width=6] (0,-1)--(1,-1);
\draw [red, line width=6] (1,-1)--(2,-1);
\draw [green, line width=6] (2,-1)--(3,-1);
\draw [pink, line width=6] (3,-1)--(4,-1);
\draw [purple, line width=6] (4,-1)--(5,-1);
\draw [lightgray, line width=6] (5,-1)--(6,-1);
\draw[<->,thick,cyan] (0.5,-1.5) to [out=305,in=225] (1.5,-1.5); 
\draw[<->,thick,cyan] (1.5,-1.5) to [out=305,in=225] (2.5,-1.5);
\draw[<->,thick,cyan] (2.5,-1.5) to [out=305,in=225] (3.5,-1.5);
\draw[<->,thick,cyan] (3.5,-1.5) to [out=305,in=225] (4.5,-1.5);
\draw[<->,thick,cyan] (4.5,-1.5) to [out=305,in=225] (5.5,-1.5);
\node at (0.5,0.3) {I};
\node at (1.5,0.3) {II};
\node at (2.5,0.3) {III};
\node at (3.5,0.3) {IV};
\node at (4.5,0.3) {V};
\node at (5.5,0.3) {VI};

enter image description here

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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