8

I used Python to make the plot shown below (saved as png).

It should have a common colorbar and all data is read from a h5 file, but I thought saving it to a txt file or something using a Python script to read in for the TikZ figure.

There are 5 plots and 1 colorbar:

The first plots only has one variable (with values 0,25,33,50,66,75 %), each colored square represents the corresponding output, which can be represented by an array of length 6.

The four other plots have two variables (with values [0,25,33,50,66,75 %] and [0,1,2,3,4,5,6,7,8]) and can thus be represented by a 6x9 matrix.

I would like to make a TikZ figure just like the PNG, but off course with non-overlapping text and maybe a title for each subplot and a better outline of the colorbar (the png was quick and dirty to be able to quickly view the output).

Can anyone help me out here?

(If having the values is usefull, please tell me in what format it would be easiest and I'll upload a txt file asap.)

Edit: Adding the data in data.txt

data.txt

Edit2: I forgot to mention that I would like to be able to use \figureheight and \figurewidth, defined in the tex file, to adjust the dimensions (like I did in the figure from another question).

enter image description here

  • 2
    I'd suggest using pgfplots. Therefore it would be helpful to have the tabular values in a txt file. – Henri Menke Sep 19 '13 at 15:55
  • I added the 'data.txt' link. I did not include the 0..8 range because I thought that might make things more complicated than necessary, but I did include the y-labels – BartV Sep 19 '13 at 22:56
  • If you're using matplotlib, there is a TikZ/PGF backend – G. Poore Sep 20 '13 at 0:24
  • @Poore I tried using the tikz/pgf backend (had to update matplotlib for it), but the output is not the most structured. I thought importing the data from a file would be more clear. Something I also forgot to mention in my origiinal question is thqt I want to be able to adjust the size of the figure in my tex document, which I did up till now by using width=\figurewidth, height=\figureheight, as arguments in \begin{axis}, with \figurewidth and \figureheight defined in my tex file. I don't see any possibility for this using the backend route. – BartV Sep 23 '13 at 10:55
4

As I wasn't happy with what I could achieve with pgfplots, I tried writing something myself. Basically it's a foreach loop, which computes the color for a specific value and then draws a square. There were some obstacles, as I learned you need \xglobal to make color definitions global. The result is still far from automatic, but I'm thinking about adding a key-value interface via pgfkeys. Anyway, here's what I have so far:

Code

\documentclass[tikz,border=2mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.9}
\usepackage{xifthen}

\begin{document}

\newcommand{\mycolorbar}[6]% height,width,colors,label min,label max,label step
{   \foreach \x [count=\c] in {#3}{ \xdef\numcolo{\c}}
  \pgfmathsetmacro{\pieceheight}{#1/(\numcolo-1)}
  \xdef\lowcolo{}
  \foreach \x [count=\c] in {#3}
  { \ifthenelse{\c = 1}
    {}
    {   \fill[bottom color=\lowcolo,top color=\x] (0,{(\c-2)*\pieceheight}) rectangle (#2,{(\c-1)*\pieceheight});
    }
    \xdef\lowcolo{\x}
  }
  \draw[thick] (0,0) rectangle (#2,#1);
  \pgfmathsetmacro{\secondlabel}{#4+#6}
  \pgfmathsetmacro{\lastlabel}{#5+0.01}
  \pgfkeys{/pgf/number format/.cd,fixed,precision=2}
  \foreach \x in {#4,\secondlabel,...,\lastlabel}
  { \draw[thick] (#2,{(\x-#4)/(#5-#4)*#1}) -- ++ (0.15,0) node[right] {\pgfmathprintnumber{\x}};
  }
}

\newcommand{\mycolor}[4]% z, min, max, colors
{   \foreach \x [count=\c] in {#4}
    { \xdef\numcolors{\c}
    }
    \foreach \x [count=\c] in {#4}  
    {   \ifthenelse{\c > 1}
        {   \pgfmathsetmacro{\lowbound}{(\c-2)/(\numcolors-1)*(#3-#2)+#2}
            \pgfmathsetmacro{\upbound}{(\c-1)/(\numcolors-1)*(#3-#2)+#2}
            \pgfmathtruncatemacro{\thisinterval}{and(#1>=\lowbound,#1<\upbound)?1:0}
            \ifthenelse{\thisinterval = 1}
            {   \pgfmathtruncatemacro{\myperc}{(#1-\lowbound)/(\upbound-\lowbound)*100}
                \pgfmathtruncatemacro{\myinvperc}{100-\myperc}
                \xglobal\colorlet{myfillcolor}{rgb:\lowcolor,\myinvperc;\x,\myperc}
            }
            {}
            \pgfmathtruncatemacro{\isbigger}{#1>#3?1:0}
            \ifthenelse{\isbigger=1}
            {   \xglobal\colorlet{myfillcolor}{\x}
            }
            {}
        }
        {   \pgfmathtruncatemacro{\issmaller}{#1<#2?1:0}
            \ifthenelse{\issmaller=1}
            {   \xglobal\colorlet{myfillcolor}{\x}
            }
            {}
        }
        \xdef\lowcolor{\x}
    }
}

\begin{tikzpicture}[scale=0.4]
    \foreach \z [count=\cz] in {4.21, 4.21, 4.21, 4.21, 4.21, 4.38, 4.38, 4.38, 4.38, 14.74, 14.74, 14.74, 14.74, 14.74, 15.11, 15.11, 16.51, 18.54, 23.02, 23.02, 23.02, 23.02, 23.02, 22.84, 22.84, 24.77, 26.93, 25.18, 25.18, 25.18, 25.18, 25.18, 25.03, 25.03, 25.27, 28.47, 37.71, 37.71, 37.71, 37.71, 37.71, 37.71, 38.51, 40.13, 39.68, 33.62, 33.62, 33.62, 33.62, 33.62, 33.62, 34.02, 34.02, 31.52}
    {   \definecolor{myfillcolor}{rgb}{128,128,128}
        \mycolor{\z}{0}{45}{blue!50!black, blue!50!gray, blue!50!cyan, green!50!cyan, lime, yellow!50!orange, orange, red, red!50!black}
        \fill[myfillcolor] ({mod(\cz-1,9)},{div(\cz-1,9)}) rectangle ++(1,1) node[pos=0.5,black] {};
    }
    \draw[thick] (0,0) rectangle (9,6);
    \foreach \x in {0,...,8}
    { \draw[thick] (\x+0.5,6) -- (\x+0.5,5.7);
        \draw[thick] (\x+0.5,0.3) -- (\x+0.5,0) node[below] {\tiny\x};
    }
    \foreach \y [count=\c] in {0,25,33,50,66,75}
    { \draw[thick] (9,\c-0.5) -- (8.7,\c-0.5);
        \draw[thick] (0.3,\c-0.5) -- (0,\c-0.5) node[left] {\tiny\y};
    }
    \node[below] at (4.5,-0.5) {first raster};

\begin{scope}[shift={(11,0)}]
    \foreach \z [count=\cz] in {1,...,54}
    {   \definecolor{myfillcolor}{rgb}{128,128,128}
        \pgfmathsetmacro{\zr}{rnd*45}
        \mycolor{\zr}{0}{45}{blue!50!black, blue!50!gray, blue!50!cyan, green!50!cyan, lime, yellow!50!orange, orange, red, red!50!black}
        \fill[myfillcolor] ({mod(\cz-1,9)},{div(\cz-1,9)}) rectangle ++(1,1) node[pos=0.5,black] {};
    }
        \draw[thick] (0,0) rectangle (9,6);
    \foreach \x in {0,...,8}
    { \draw[thick] (\x+0.5,6) -- (\x+0.5,5.7);
        \draw[thick] (\x+0.5,0.3) -- (\x+0.5,0) node[below] {\tiny\x};
    }
    \foreach \y [count=\c] in {0,25,33,50,66,75}
    { \draw[thick] (9,\c-0.5) -- (8.7,\c-0.5);
        \draw[thick] (0.3,\c-0.5) -- (0,\c-0.5) node[left] {\tiny\y};
    }
    \node[below] at (4.5,-0.5) {chaos};
\end{scope}

\begin{scope}[shift={(0,-8)}]
    \foreach \z [count=\cz] in {1,...,54}
    {   \definecolor{myfillcolor}{rgb}{128,128,128}
        \pgfmathsetmacro{\zr}{(mod(\cz-1,9)+div(\cz-1,9))*3}
        \mycolor{\zr}{0}{45}{blue!50!black, blue!50!gray, blue!50!cyan, green!50!cyan, lime, yellow!50!orange, orange, red, red!50!black}
        \fill[myfillcolor] ({mod(\cz-1,9)},{div(\cz-1,9)}) rectangle ++(1,1) node[pos=0.5,black] {};
    }
        \draw[thick] (0,0) rectangle (9,6);
    \foreach \x in {0,...,8}
    { \draw[thick] (\x+0.5,6) -- (\x+0.5,5.7);
        \draw[thick] (\x+0.5,0.3) -- (\x+0.5,0) node[below] {\tiny\x};
    }
    \foreach \y [count=\c] in {0,25,33,50,66,75}
    { \draw[thick] (9,\c-0.5) -- (8.7,\c-0.5);
        \draw[thick] (0.3,\c-0.5) -- (0,\c-0.5) node[left] {\tiny\y};
    }
    \node[below] at (4.5,-0.5) {gradient};
\end{scope}

\begin{scope}[shift={(11,-8)}]
    \foreach \z [count=\cz] in {1,...,54}
    {   \definecolor{myfillcolor}{rgb}{128,128,128}
        \pgfmathsetmacro{\zr}{pow(mod(\cz-1,9),2)+pow(div(\cz-1,9),2)-11}
        \mycolor{\zr}{0}{45}{blue!50!black, blue!50!gray, blue!50!cyan, green!50!cyan, lime, yellow!50!orange, orange, red, red!50!black}
        \fill[myfillcolor] ({mod(\cz-1,9)},{div(\cz-1,9)}) rectangle ++(1,1) node[pos=0.5,black] {};
    }
    \draw[thick] (0,0) rectangle (9,6);
    \foreach \x in {0,...,8}
    { \draw[thick] (\x+0.5,6) -- (\x+0.5,5.7);
        \draw[thick] (\x+0.5,0.3) -- (\x+0.5,0) node[below] {\tiny\x};
    }
    \foreach \y [count=\c] in {0,25,33,50,66,75}
    { \draw[thick] (9,\c-0.5) -- (8.7,\c-0.5);
        \draw[thick] (0.3,\c-0.5) -- (0,\c-0.5) node[left] {\tiny\y};
    }
    \node[below] at (4.5,-0.5) {floor \& roof};
\end{scope}

\begin{scope}[shift={(21,-8)}]
    \mycolorbar{14}{1}{blue!50!black, blue!50!gray, blue!50!cyan, green!50!cyan, lime, yellow!50!orange, orange, red, red!50!black}{0}{45}{5}
\end{scope}
\end{tikzpicture}

\end{document}

Output

enter image description here

  • the \mycolorbar gives me an error: Package xcolor Error: Undefined color `'. Did you come across this? – BartV Nov 27 '13 at 3:55
  • Previous comment was on the use in QTikz. It seems to work in an example tex in texmaker, hopefully when edited to reflect my results it will still work and also work inside my document. – BartV Nov 27 '13 at 4:30
  • Works great for this example (or one with a range 0..14), but now it seems to give trouble with a range of approx 0.68..1.85. Could there be something wrong with the \mycolor? At the moment, I don't understand it well enough to understand it all. The colorbar seem ok, but it doesn't correspond to the colors in the figure (where a lot of the boxes are white...) – BartV Nov 27 '13 at 19:53
  • It was so simple... I think... Just added +#2 to \lowbound and \upbound – BartV Nov 27 '13 at 23:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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