12

I would like to make the following figure: enter image description here

My already code is:

\documentclass{standalone}
\usepackage[english, greek]{babel}
\usepackage{ucs} 
\usepackage[utf8x]{inputenc}
\usepackage[usenames,dvipsnames]{xcolor}
\usepackage{tikz}
\usepackage{amssymb}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amsthm}
\usepackage{graphicx}
\usepackage{epstopdf}
\usepackage[usenames,dvipsnames]{xcolor}


\begin{document}


\begin{tikzpicture}
\draw[very thick, ->] (0,0)--(0,5) node[left] {Επίπεδο Οικονομικής Δραστηριότητας};
\draw[very thick, ->] (0,0)--(5,0) node[below right] {Χρόνος};
\draw[thick, Blue, -] (.7,.7) node[above left] {$A$}--(4.2,4) node[above right]{$B$};

\end{tikzpicture}

\end{document}

How can I make the curvy part of the figure (red part)? How can I write each word rotated?

The picture is more like the following:enter image description here

Y_gr
  • 3,322

4 Answers4

20

You can superimpose an attenuated sine function over the linear growth function to get something similar. To place the nodes, you can add node [pos=<fraction>, sloped] {<text>} at the end of the \addplot command:

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}


\begin{document}

\begin{tikzpicture}
\begin{axis}[
    domain=0:6*pi,
    samples=100,
    axis lines*=left,
    xtick=\empty, ytick=\empty,
    width=13cm, height=8cm
]

\addplot [thick, gray] {x};
\addplot [thick, black] {x + 4*sin(deg(x)) * sin(deg(x/6))^0.5}
    node [pos=0.1, anchor=south] {Peak}
    node [pos=0.3, anchor=south, sloped] {Expansion}
    node [pos=0.49, anchor=south, sloped] {Recession}
;


\end{axis}
\end{tikzpicture}

\end{document}

As suggested by Mico, here's an explanation of the function. Basically, it's just the sum of a linear function and a sine wave:

This looks alright, but notice that the gradient at the start and end of the plot is much steeper than the linear function, while the plot in giannis' second image has gradients that are equal (or at least similar) to the gradient of the linear function.

One way to get something like that is to attenuate the sine function by multiplying it with a function that's small near the start and end of the domain, and close to 1 around the center of the domain. An example of such a function is sin(deg(x/6))^0.5 (found using a bit of trial and error).

Putting it all together:

Jake
  • 232,450
11

Here's a version in Metapost that automagically finds the right places for the labels on the wave, using the directiontime function that finds the point on a path when it's going in a specified direction.

enter image description here

Note that directiontime will normally find the earliest point along the path that has the specified direction, so here I had to put it in a loop and step along the path. directiontime returns -1 when the direction is not found; I used that to end the loop.

I've also re-used the labels by saving them as picture variables.

This is wrapped up in luamplib so you need to compile it with lualatex:

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\mplibtextextlabel{enable}
\usepackage{fontspec}
\setmainfont{Helvetica}
\begin{document}
\begin{mplibcode}
beginfig(1);

% fiddle with the parameters to get a nice rising wave path wave; wave = (origin for t=1 step 1 until 3360 + 24: -- (2/3t,70 sind(t)) shifted (0,1/3t) endfor) scaled 3/4 shifted (21,34);

% draw the straight arrow and the wave on top drawarrow point 0 of wave -- point 3*360 of wave scaled 1.05 dashed evenly withcolor .5[blue, white]; draw wave withpen pencircle scaled 1 withcolor .67 green;

% label pictures picture s[]; s1 = thelabel.top("peak", origin); s2 = thelabel.bot("trough", origin); s3 = thelabel.top("expansion", origin); s4 = thelabel.top("recession", origin);

% add the labels in the "right" places t = 0; n = 0; forever: dt := directiontime right of subpath(t,infinity) of wave; exitif dt < 0; t := t + dt; n := n + 1; if odd(n): draw s1 shifted point t of wave withcolor .67 blue;
if n>1: draw s3 rotated angle direction t-dt/2 of wave shifted point t-dt/2 of wave ; fi else: draw s2 shifted point t of wave withcolor .67 red;
draw s4 rotated angle direction t-dt/2 of wave shifted point t-dt/2 of wave; fi endfor

% do the axes and titles path xx, yy; xx = origin -- (xpart point infinity of wave, 0); yy = origin -- (0, ypart point infinity of wave); drawarrow xx; drawarrow yy;

label.bot(TEX("Time") scaled 1.2, point 1/2 of xx); label.lft(TEX("Level of real output") scaled 1.2 rotated 90, point 1/2 of yy); label.urt(TEX("The business cycle") scaled 1.44, point 0.8 of yy shifted 10 right) withcolor .8 red;

endfig; \end{mplibcode} \end{document}

Because the version of Helvetica on my Mac includes a full range of Greek characters, and because lualatex fully supports Unicode, all you have to do to get a Greek version is to replace the seven labels with Greek versions:

s1 = thelabel.top("κρίση", origin);
s2 = thelabel.bot("ύφεση", origin);
s3 = thelabel.top("άνοδος", origin);
s4 = thelabel.top("κἀθοδος", origin);

label.bot(TEX("Χρὀνος") scaled 1.2, point 1/2 of xx); label.lft(TEX("Επἰπεδο οικονομικἠς δραστηριὀτητας") scaled 1.2 rotated 90, point 1/2 of yy); label.urt(TEX("Οι φἀσεις του Οικονομικοὐ Κὐκλου") scaled 1.44, point 0.8 of yy shifted 10 right) withcolor .8 red;

If you put these versions in the right places and recompile you should get:

enter image description here

Old, original version

When I originally answered this question, I was still using old-fashioned Metapost compiled directly with mpost. The font management is a bit harder back then. I've left the old versions for comparions.

Compile this one with mpost to get PostScript output.

prologues := 3;
outputtemplate := "%j%c.eps";

beginfig(1);

string ff; ff = "phvr8r";

% fiddle with the parameters to get a nice rising wave path wave; wave = (origin for t=1 step 1 until 3360 + 24: -- (2/3t,70 sind(t)) shifted (0,1/3t) endfor) scaled 3/4 shifted (21,34);

% draw the straight arrow and the wave on top drawarrow point 0 of wave -- point 3*360 of wave scaled 1.05 dashed evenly withcolor .5[blue, white]; draw wave withpen pencircle scaled 1 withcolor .67 green;

% labels picture s[]; % center each label and push it up/down slightly s1 = "peak" infont ff; s1 := s1 shifted (-1/2 xpart urcorner s1, 6); s2 = "trough" infont ff; s2 := s2 shifted (-1/2 xpart urcorner s2, -12); s3 = "expansion" infont ff; s3 := s3 shifted (-1/2 xpart urcorner s3, 6); s4 = "recession" infont ff; s4 := s4 shifted (-1/2 xpart urcorner s4, 6);

% add the labels in the "right" places t = 0; n = 0; forever: dt := directiontime right of subpath(t,infinity) of wave; exitif dt < 0; t := t + dt; n := n + 1; if odd(n): draw s1 shifted point t of wave withcolor .67 blue;
if n>1: draw s3 rotated angle direction t-dt/2 of wave shifted point t-dt/2 of wave ; fi else: draw s2 shifted point t of wave withcolor .67 red;
draw s4 rotated angle direction t-dt/2 of wave shifted point t-dt/2 of wave; fi endfor

% do the axes and titles path xx, yy; xx = origin -- (xpart point infinity of wave, 0); yy = origin -- (0, ypart point infinity of wave); drawarrow xx; drawarrow yy;

label.bot("Time" infont ff scaled 1.2, point 1/2 of xx); label.lft("Level of real output" infont ff scaled 1.2 rotated 90, point 1/2 of yy); label.top("The business cycle" infont ff scaled 1.44, point 0.8 of yy shifted 108 right) withcolor .8 red;

% add a little space all round setbounds currentpicture to bbox currentpicture; endfig; end.

To produce a Greek version (the old way) you need to switching the TeX processing to LaTeX with mpost -tex=latex and use the gfsneohellenic package.

enter image description here

beginfig(2);

verbatimtex \documentclass{article} \usepackage[english,greek]{babel} \usepackage[iso-8859-7]{inputenc} \usepackage{cmbright} \usepackage[default]{gfsneohellenic} \begin{document} etex

% fiddle with the parameters to get a nice rising wave path wave; wave = (origin for t=1 step 1 until 3360 + 24: -- (2/3t,70 sind(t)) shifted (0,1/3t) endfor) scaled 3/4 shifted (21,34);

% draw the straight arrow and the wave on top drawarrow point 0 of wave -- point 3*360 of wave scaled 1.05 dashed evenly withcolor .5[blue, white]; draw wave withpen pencircle scaled 1 withcolor .67 green;

% labels picture s[]; % center each label and push it up/down slightly s1 = btex \textneohellenic{kr'ish} etex; s1 := s1 shifted (-1/2 xpart urcorner s1, 6); s2 = btex \textneohellenic{'ufesh} etex; s2 := s2 shifted (-1/2 xpart urcorner s2, -12); s3 = btex \textneohellenic{'anodoc} etex; s3 := s3 shifted (-1/2 xpart urcorner s3, 6); s4 = btex \textneohellenic{k'ajodoc} etex; s4 := s4 shifted (-1/2 xpart urcorner s4, 6);

% add the labels in the "right" places numeric t, n, dt; t = 0; n = 0; forever: dt := directiontime right of subpath(t,infinity) of wave; exitif dt < 0; t := t + dt; n := n + 1; if odd(n): draw s1 shifted point t of wave withcolor .67 blue;
if n>1: draw s3 rotated angle direction t-dt/2 of wave shifted point t-dt/2 of wave ; fi else: draw s2 shifted point t of wave withcolor .67 red;
draw s4 rotated angle direction t-dt/2 of wave shifted point t-dt/2 of wave; fi endfor

% do the axes and titles path xx, yy; xx = origin -- (xpart point infinity of wave, 0); yy = origin -- (0, ypart point infinity of wave); drawarrow xx; drawarrow yy;

label.bot(btex \textneohellenic{Qr'onoc} etex scaled 1.2, point 1/2 of xx); label.lft(btex \textneohellenic{Ep'ipedo oikonomik'hc drasthri'othtac} etex scaled 1.2 rotated 90, point 1/2 of yy); label.top(btex \textneohellenic{Oi f'aseic tou Oikonomiko'u K'uklou} etex scaled 1.44, point 0.8 of yy shifted 160 right) withcolor .8 red;

% add a little space all round setbounds currentpicture to bbox currentpicture; endfig;

Thruston
  • 42,268
7

Here is something that should get you started. You can adjust the text at the vrious positions or delete any nodes that are not desired:

enter image description here

Notes:

  • This isn't quite as flexible as I had thought it would be when I started, so perhaps someone else will come up with a more clever way to do this.

Code:

\documentclass{article}
\usepackage{xcolor}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\newcommand{\MyNode}[3][]{% % #1 = node options % #2 = x location % #3 = text \node [#1] at (axis cs: #2pi, {sin(deg(#2*pi))}) {#3}; }

\tikzset{My Node Style/.style={font=\tiny, sloped}, above, text=black}

\newcommand*{\RotateAngle}{25}%

\begin{document} \begin{tikzpicture}[rotate=\RotateAngle, scale=1.0] \begin{axis}[ axis y line=none, axis x line=none, ] \addplot [mark=none, ultra thick, draw=red, samples=200, domain=-0.3pi:4.2pi] {sin(deg(x))};

%% Easier to place the nodes when the domain is a multiple of 2pi, so we %% redo the plot without actually drawing it. \addplot [mark=none, ultra thick, draw=none, samples=200, domain=-1pi:5pi] {sin(deg(x))} node [pos=0.20, My Node Style] {$0.20$} node [pos=0.30, My Node Style] {$0.30$} node [pos=0.35, My Node Style] {$0.35$} node [pos=0.55, My Node Style] {$0.55$} node [pos=0.65, My Node Style] {$0.65$} node [pos=0.675, My Node Style] {$0.675$} node [pos=0.81, My Node Style] {$0.81$} node [pos=0.86, My Node Style] {$0.86$} ;

%% nodes at the peaks are better placed separately. Am assuming you want
%% these labels horizontal hence have added rotate=-\RotateAngle
\MyNode[My Node Style, rotate=-\RotateAngle, above]{0.5}{$0.5\pi$};
\MyNode[My Node Style, rotate=-\RotateAngle, below]{1.5}{$1.5\pi$};
\MyNode[My Node Style, rotate=-\RotateAngle, above]{2.5}{$2.5\pi$};
\MyNode[My Node Style, rotate=-\RotateAngle, below]{3.5}{$3.5\pi$};

%% Draw the straight line
\addplot [mark=none, ultra thick, blue, domain=-1.5*pi:6*pi] {0}
    node [text=black, pos=0, rotate=-\RotateAngle, left] {A}
    node [text=black, pos=1, rotate=-\RotateAngle, right] {B}
    ;

\end{axis}

\draw [rotate=-\RotateAngle, gray, thick, -latex] (-2,0) -- (-2,7) node [left, align=left, text=black, text width=1.1cm, inner sep=0, outer sep=0] {$x$-Axis Label}; \draw [rotate=-\RotateAngle, gray, thick, -latex] (-2,0) -- (5,0) node [below, text=black] {$y$-axis Label}; \end{tikzpicture} \end{document}

Peter Grill
  • 223,288
  • 1
    Isn't that red line supposed to be a function of time? – Manuel Nov 05 '14 at 21:16
  • @Manuel: Have revised solution so it is a function of time. – Peter Grill Nov 06 '14 at 03:43
  • Mmm… I don't know what you did, I mean, for each value of time, there can't be two values of the red line. But may be they can… – Manuel Nov 06 '14 at 08:25
  • 1
    I think Manuel proposes something like sin(deg(x))+.15*x+3 (just an example) instead of rotating sin(deg(x)). – Ignasi Nov 06 '14 at 08:37
  • Looking at the original figure from the question it also looks like multiple values for the same time, so I don't think this is the issue. – Markus Nov 06 '14 at 08:44
  • @Markus Yeah, may be I'm going too far, but still, I think that the “low quality” of that image led me to think that the function is wrong there (just painted rotating a sinoidal function) and it should be like Ignasi's equation. But yeah, I shut up right know, I'm talking about something I don't know :P – Manuel Nov 06 '14 at 09:36
  • 1
    @Markus Nah, after re-reading, the fact that it's a function of time… I think that it's obviously true what I'm saying. – Manuel Nov 06 '14 at 09:38
  • 1
    The graph is supposed to be a function of time: it indicates the trajectory of some macroeconomic indicator (e.g., real output, or real gross domestic product, GDP) over time ("chronos" in the OP's graph). Hence, one must not create a graph that makes it look like the economic indicator can take on two (or more!) possible values at any point in time. – Mico Nov 06 '14 at 10:09
  • @Manuel: Sorry, that was not clear to me from the original question. But since Jake already posted a better solution, I won't bother adjusting this any further. – Peter Grill Nov 06 '14 at 16:43
  • @PeterGrill Don't worry, it was me who didn't explain clearly. – Manuel Nov 06 '14 at 17:36
6

Here's another option using a "pure" TikZ approach. The curve is drawn using control points:

enter image description here

The code (control the value for \Angle to get the desired inclination for the path):

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.markings,backgrounds}

\begin{document}

\begin{tikzpicture}
\def\Angle{25}
\begin{scope}[rotate=\Angle]
\draw[thick,dashed,-latex]
  (1cm,0cm) -- (13cm,0cm);
\draw[
  thick,
  draw=green!80!black,
  decoration={
    markings,
    mark=at position 0.2 with {\node[below,rotate=-60+\Angle] {Recession};},
    mark=at position 0.4 with {\node[above,rotate=60+\Angle] {Expansion};},
    mark=at position 0.6 with {\node[below,rotate=-60+\Angle] {Recession};},
    mark=at position 0.8 with {\node[above,rotate=60+\Angle] {Expansion};}
  },
  postaction={decorate}
  ]
  (2cm,0cm) .. controls ++(0.75cm,1.5cm) and ++(-0.75cm,1.5cm) .. 
    node[above=4pt,anchor=east,blue] {Peak}
  (4cm,0cm) .. controls ++(0.75cm,-1.5cm) and ++(-0.75cm,-1.5cm) .. 
    node[below=4pt,anchor=west,red!80!black] {Trough}
  (6cm,0cm) .. controls ++(0.75cm,1.5cm) and ++(-0.75cm,1.5cm) .. 
    node[above=4pt,anchor=east,blue] {Peak}
  (8cm,0cm) .. controls ++(0.75cm,-1.5cm) and ++(-0.75cm,-1.5cm) .. 
    node[below=4pt,anchor=west,red!80!black] {Trough}
  (10cm,0cm) .. controls ++(0.75cm,1.5cm) and ++(-0.75cm,1.5cm) .. 
    node[above=4pt,anchor=east,blue] {Peak}
  (12cm,0cm);
\end{scope}
\begin{pgfonlayer}{background}
\filldraw[
  shade,
  top color=cyan!18,
  bottom color=orange!2,
]
  ([shift={(-1cm,1cm)}]current bounding box.north west)
    rectangle
  ([shift={(1cm,-1cm)}]current bounding box.south east);
\end{pgfonlayer}
\node[below=5pt] 
  at (current bounding box.south)
  {Time};
\node[left=20pt,rotate=90,anchor=north] 
  at (current bounding box.west)
  {Level of real output};
\node[below=7pt,anchor=north,font=\Large,text=red] 
  at (current bounding box.north)
  {The business cycle};
\end{tikzpicture}

\end{document}
Gonzalo Medina
  • 505,128