2

Is there a LaTeX macro that can reproduce the OECD's "Magic Diamond" that is an indication of a country's economic performance?

Here's the "Magic Diamond" overview:

And here's what a specific "Magic Diamond" might look like showing a "before and after" or a "now and then" or "country A and country B" with two diamonds on the same axes (axes not labeled nor scaled with the economic indicators here - legend is missing too).

Ideally the macro would accept the four economic indicator numbers, or a sequence of sets of them, axis limits for each indicator, and then produce the diagram as shown in the images above or like this one below.

enter image description here

  • 1
    Yes, it is possible. But surely you will need to specify more than just the four values since the axis scales are different for each of them. –  Jun 02 '20 at 18:48
  • @Schrödinger'scat Yes, I updated the question to include the axis limits for each indicator. – rickhg12hs Jun 02 '20 at 18:55
  • @rickhg12hs I presume you want to input real data to be able to update your graph. If so, would you have a set of data that could be used in your MWE ? – JeT Jun 02 '20 at 19:25
  • @JeT I would be drawing data from one or more of the many economic statistics websites. The quad diagram above seems to have axes limits of [1,5, 3.5] for GDP, [2, 12] for UNR (note the inverted scale), [-1, 5] for PCP (also inverted scale), and [-150, 100] for CB (inverted scale). Note that it would be convenient to assign each economic indicator to any semi-axis and specify the precise text. An example from the "Total OECD" for June 1986 looks to be about [GDP, UNR, PCP, CB] = [3.1, 8.2, 3.2, 7]. – rickhg12hs Jun 02 '20 at 20:18
  • Is it a sort of radar chart with four values and four specific scales ? – Paul Gaborit Jun 02 '20 at 22:29
  • @PaulGaborit Yes, I think it is. – rickhg12hs Jun 02 '20 at 23:43
  • 1
    Then you might be interested in the tkz-kiviat package, which originated from this answer. –  Jun 03 '20 at 02:26
  • 1
    @Schrödinger'scat @PaulGaborit I don't see how to have independent axis scales with package tkz-kiviat. – rickhg12hs Jun 03 '20 at 02:52
  • 2
    Yes, I agree that this does not seem to be supported. The comment above was just to link to these plots, which seem to be very much like radar plots. –  Jun 03 '20 at 02:59

2 Answers2

2

The answer to the question is yes, this can be done. Here is a prototype example. It sets up for different coordinate systems with their individual scalings, and plots the coordinates in those.

\documentclass[tikz,border=3mm]{standalone}
\tikzset{pics/Magic Diamond/.style={code={
    \tikzset{Magic Diamond/.cd,#1}%
    \def\pv##1{\pgfkeysvalueof{/tikz/Magic Diamond/##1}}% 
    \draw (-\pv{size}/2,-\pv{size}/2) rectangle (\pv{size}/2,\pv{size}/2);
    \foreach \XX [count=\YY] in {A,B,C,D}
    {\begin{scope}[shift={(-\YY*90:\pv{size}/2)},rotate={-90-\YY*90}]
     \pgfmathsetmacro{\first}{\pv{\XX min}}
     \pgfmathsetmacro{\next}{\first+\pv{\XX step}}
     \pgfmathifisint{\next}{\pgfmathtruncatemacro{\next}{\next}}{}
     \pgfmathsetmacro{\last}{\pv{\XX max}}
     \foreach \ZZ in {\first,\next,...,\last}
     {\draw ({(\ZZ-\first)*\pv{size}/(2*(\last-\first))},0) 
     node[anchor=180-\YY*90,node contents/.expanded=\ZZ] --     
      ++ (0,-\pv{tick length});}
     \draw[-stealth] (0,1) -- node[midway,anchor=180-\YY*90,
        node contents/.expanded=\pv{\XX}]{} (\pv{size}/2,1); 
    \end{scope}}
    \edef\lstABCD{"X","A","B","C","D"}
    \edef\DataSets{\pv{data}}
    \foreach \DataSet [count=\nData] in \DataSets
    {%\typeout{\DataSet}
     \foreach \DataPoint [count=\nDataPoint] in \DataSet
     {
     \pgfmathsetmacro{\currid}{{\lstABCD}[\nDataPoint]}
     \pgfmathsetmacro{\xtransformed}{(\DataPoint-\pv{\currid min})*%
        \pv{size}/(2*(\pv{\currid max}-\pv{\currid min}))}
     %\typeout{\nDataPoint,\DataPoint,\xtransformed}
     \path (-90-90*\nDataPoint:\xtransformed pt) coordinate (tmp-\nDataPoint);  
     }
     \pgfmathsetmacro{\mystyle}{{\pv{styles}}[\nData-1]}
     \draw[style/.expanded=\mystyle]  (tmp-1) -- (tmp-2) -- (tmp-3) -- (tmp-4) -- cycle;
    }
    }},Magic Diamond/.cd,size/.initial=10cm,tick length/.initial=3pt,
        Amax/.initial=5,Amin/.initial=0,Astep/.initial=1,A/.initial=CB,
        Bmax/.initial=5,Bmin/.initial=0,Bstep/.initial=1,B/.initial=PCB,
        Cmax/.initial=5,Cmin/.initial=0,Cstep/.initial=1,C/.initial=UNR,
        Dmax/.initial=5,Dmin/.initial=0,Dstep/.initial=1,D/.initial=GDP,
        data/.initial={{1,2,3,4},{1.5,2.5,1.5,2.5}},
        styles/.initial={"solid","dashed","red","orange","blue"}}

\begin{document}
\begin{tikzpicture}
 \pic{Magic Diamond};   
\end{tikzpicture}
\end{document}

enter image description here

  • Thank you! I was hoping a package/macro already existed and I just couldn't find it. I will indeed examine your prototype. – rickhg12hs Jun 02 '20 at 20:22
  • 3
    @rickhg12hs There are ternary diagrams, which are described in section 5.13 Ternary Diagrams of the pgfplots manual v1.17. They come close conceptually but are AFAIK limited to 3 directions. I would not at all be surprised if something like the above existed in some form somewhere, but I am not aware of any post of that sort. –  Jun 02 '20 at 20:34
  • @Schrödinger'scat This answer might become a classic for economists. – JeT Jun 03 '20 at 13:29
  • 1
    @JeT I think the second one may be more versatile. (I just fixed a really stupid bug there... ) –  Jun 03 '20 at 15:02
2

I usually do not add two answers, but this is a very different strategy than the other one. It uses groupplots, and is based on pgfplots, so highly customizable. All you need to do is to specify the data in a table such as

CB PCB UNR GDP
1 2 3 4
1.5 2.5 1.5 2.5
2 3 2.5 3.5
4 3 2 1

and the code will do the rest such as extracting the column names, finding the ranges, and producing the plots.

\documentclass[tikz,border=3mm]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=1.17}
\pgfplotsset{% https://tex.stackexchange.com/a/75811/121799
    name nodes near coords/.style={nodes near coords={},
        every node near coord/.append style={anchor=center,coordinate,
            name=#1-\coordindex,
            alias=#1-last,
        },
    },
    name nodes near coords/.default=coordnode
}

\begin{document}
\begin{tikzpicture}
\pgfplotstableread{
CB PCB UNR GDP
1 2 3 4
1.5 2.5 1.5 2.5
2 3 2.5 3.5
4 3 2 1
}{\loadedtable}
\edef\mystyles{"solid","dashed","red","orange","blue"}
\pgfplotstableforeachcolumn\loadedtable\as\col{%
\ifcase\pgfplotstablecol
\edef\mycolA{\col}%
\or
\edef\mycolB{\col}%
\or
\edef\mycolC{\col}%
\or
\edef\mycolD{\col}%
\or
\fi}
\pgfplotstablegetrowsof{\loadedtable}%
\pgfmathtruncatemacro{\numrows}{\pgfplotsretval-1}%
\begin{groupplot}[
    group style={group name=top,group size=2 by 2,
        horizontal sep=0pt,vertical sep=0pt},height=4cm,width=4cm] 
\nextgroupplot[xtick=\empty,yticklabel pos=lower,ylabel=\mycolA,
    enlarge y limits=0.3,xmin=-1,xmax=0]
\addplot[only marks,name nodes near coords=\mycolA] 
    table[y expr=\thisrow{\mycolA},x expr=0]  {\loadedtable}; 
\nextgroupplot[ytick=\empty,xticklabel pos=upper,xlabel=\mycolB,
    enlarge x limits=0.3,ymax=1,ymin=0]
\addplot[only marks,name nodes near coords=\mycolB] 
    table[x expr=\thisrow{\mycolB},y expr=0]  {\loadedtable}; 
\nextgroupplot[ytick=\empty,xticklabel pos=lower,xlabel=\mycolC,
    enlarge x limits=0.3,ymax=0,ymin=-1,
    xticklabel={\pgfmathparse{-1*\tick}\pgfmathprintnumber\pgfmathresult}]
\addplot[only marks,name nodes near coords=\mycolC] 
    table[x expr=-1*\thisrow{\mycolC},y expr=0]  {\loadedtable}; 
\nextgroupplot[xtick=\empty,yticklabel pos=upper,ylabel=\mycolD,
    enlarge y limits=0.3,xmin=0,xmax=1,
    yticklabel={\pgfmathparse{-1*\tick}\pgfmathprintnumber\pgfmathresult}]
\addplot[only marks,name nodes near coords=\mycolD] 
    table[y expr=-1*\thisrow{\mycolD},x expr=0]  {\loadedtable}; 
\end{groupplot}
\foreach \X in {0,...,\numrows}
{\pgfmathsetmacro{\mystyle}{{\mystyles}[\X]}
\draw[style/.expanded=\mystyle] 
    (\mycolA-\X) -- (\mycolB-\X) -- (\mycolD-\X) -- (\mycolC-\X) -- cycle;}
\end{tikzpicture}
\end{document}

enter image description here

EDIT: Fixed an error in the tick labels of the axes pointing to the left or down.

  • Interesting! I'll study this prototype too! – rickhg12hs Jun 03 '20 at 02:59
  • 1
    @rickhg12hs fully flexible answer by schodinger's. You can use filecontents package to save in a .txt, .csv, .dat, .whatever... the set of data you use. Very easy you'll see. http://ctan.tetaneutral.net/macros/latex/contrib/filecontents/filecontents.pdf – JeT Jun 03 '20 at 16:04