0

I have two subfigures generated by Tikz, one is a curve plot and the other is a contour plot. The x-axis actually are the same so I want to align them horizontally.

I gave a minimal working example below. Some features are necessary: no y label for (b), colorbar for (b) is put on the right side.

enter image description here

I am new to tikz. I am not sure if this is really a tikz thing, which means I can align them when generating tikz figure and simply import as a graphic file using \includegraphics, or a subfigure thing, which means I do nothing in generating tikz figure, but use some resizing or shifting commands in subfigure environment to align them.

I am not which one of these two ways are better.

Any idea on that ? Thanks !

The code for MWE:

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{filecontents}
\usepackage{mathtools}
\usepackage{subfigure}

\begin{document}

\begin{figure}
    \subfigure[a]{
        \begin{tikzpicture}
            \begin{axis}[
                width = 8.7 cm,
                height = 6cm,
                scale only axis,
                xmin = -1, xmax = 1,
                ymin = -1e-3, ymax = 1e-3,
                xlabel = {Foo},
                ylabel = {Bar 1},
                ]
                \addplot[red, samples = 100] {1e-3*x};
            \end{axis}
        \end{tikzpicture}
        }
    \subfigure[b]{
        \begin{tikzpicture}
            \begin{axis}[
                width = 8.7 cm,
                height = 6 cm,
                scale only axis,
                view = {0}{90}, 
                xmin = -1, xmax = 1,
                ymin = 0, ymax =1,
                xlabel = {Foo},
                point meta min = 0, point meta max =2.5,
                colormap/jet,
                colorbar,
                colorbar style = {ytick = {0,0.5,1,1.5,2,2.5}},
                ]

                \addplot3[surf,shader = interp] {exp(x)};           

            \end{axis}
        \end{tikzpicture}
        }
    \caption{bla bla}
    \end{figure}
\end{document}
  • Do you have any code you've attempted to use so far? If so, please add it. – Null Feb 22 '16 at 3:46
  • I can't put the source file here since the data file is too large... I will try to work out a simple example and put it below. – zljt3216 Feb 22 '16 at 15:40
  • Of course you don't need to provide the full (real) data set here. You can simply add "dummy data" or don't add data to the plots at all. – Stefan Pinnow Feb 22 '16 at 17:09
  • By the way: Welcome to TeX.SX! And just in case you shouldn't know it: Have a look at our starter guide to familiarize yourself further with our format. – Stefan Pinnow Feb 22 '16 at 17:17
  • Thanks, @StefanPinnow, I edit the original post and give a MWE. – zljt3216 Feb 22 '16 at 20:03
1

You have changed your question now in that way, that you need subfigures. Hopefully this is not a requirement, because then you can do the alignment in one tikzpicture environment. Please note that I have changed your code a bit to easiliy present a kind of MWE which is in most cases the standalone documentclass. Because that does not provide a figure environment I have commented these parts of the code.

For a description, how the code works, please have a look at the comments in the code.

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usepackage{pgfplots}
    \usetikzlibrary{
        positioning,
    }
    \pgfplotsset{
        compat=newest,
        %
        % put all the stuff that is the same for the plots together here
        % in a style
        bla bla style/.style={
            scale only axis,
            width=8.7cm,
            height=6cm,
            xmin=-1,
            xmax=1,
            ymin=-1e-3,
            ymax=1e-3,
            view={0}{90},
            xlabel={Foo},
        },
    }
\begin{document}
%\begin{figure}
    \begin{tikzpicture}
        \begin{axis}[
        % use the style here
            bla bla style,
            %
        % list all stuff that is different in the plot here
            ymin=-1e-3,
            ymax=1e-3,
            ylabel={Bar 1},
            %
        % give the plot a name
            name=top plot,
        ]
            \addplot[red,samples=100] {1e-3*x};
        \end{axis}
        \begin{axis}[
        % use the style here
            bla bla style,
            %
            %%% place this axis relatively to the above plot
            % use as anchor of this plot the «north west corner of the plot ...
            anchor=north west,
            % ... and align the anchor to the anchor «below south west» of
            % the above plot ...
            at={(top plot.below south west)},
            % ... and shift it down a bit
            yshift=-2mm,
            %
        % list all stuff that is different in the plot here
            ymin=0,
            ymax=1,
            point meta min=0,
            point meta max=2.5,
            colormap/viridis,
            colorbar,
            %
        % give the plot a name
            name=below plot,
        ]
            \addplot3[surf,shader=interp] {exp(x)};
        \end{axis}

    % in case you really need the labels I suggest to place them by hand
    % and explain the labels in the (main) caption. But I would consider to
    % just refer them as «top» and «bottom» in the (main) caption
        \node (label a) at ([xshift=-2ex]top plot.left of north west) {a)};
        \node at (below plot.left of north west -| label a) {b)};
    \end{tikzpicture}
%    \caption{bla bla}
%\end{figure}
\end{document}

image showing the result of above code


Edit

As promised here is a solution with the external library of tikz/pgfplots which "automatically" externalizes pictures. This requires the shell-escape feature to be on. If you have never heard about it, here is explained how to activate it in TeXnicCenter.

Here in short how my solution works. (Only the new parts compared to the above solution are described.) To visualize the bounding box I fill it with the BB style, which adds a yellow color at the end of the picture on the background layer. This layer I have declared in advance and have set it below the main layer. Next comes the \tikzexternalize command which activates the image externaliziation. The added keys hopefully are self-explanatory. Last I have declared the new command \UseAsBB to set the bounding box of the plots. But to be sure that there are no parts from the plot already larger than declared in \UseAsBB I put the axis environment in the pgfinterruptboundingbox environment. After that I use the \UseAsBB command to set the bounding box explicitly.

More details you will find in the comments in the code.

\documentclass{article}
\usepackage{subfig}
\usepackage{tikz}
\usepackage{pgfplots}
    \usetikzlibrary{
        pgfplots.external,
    }
    % declare layer `background' and set it before the `main layer'
    % the layer is used to set and visualize the bounding box
    \pgfdeclarelayer{background}
    \pgfsetlayers{background,main}
    \tikzset{
        % define a style to apply to each `tikzpicture' to visualize the
        % bounding box by setting a fill color in the background of the
        % bounding box
        % (comment everything in the style if you are sure the bounding box
        % fits everything)
        BB style/.style={
            execute at end picture={
                \begin{pgfonlayer}{background}
                    \path [
                        fill=yellow,
                    ]
                        (current bounding box.south west)
                        rectangle
                        (current bounding box.north east);
                \end{pgfonlayer}
            },
        },
    }
    \pgfplotsset{
        compat=1.13,
        %
        % put all the stuff that is the same for the plots together here
        % in a style
        bla bla style/.style={
            scale only axis,
            width=8.7cm,
            height=6cm,
            xmin=-1,
            xmax=1,
            ymin=-1e-3,
            ymax=1e-3,
            view={0}{90},
            xlabel={Foo},
            % don't calculate the bounding box
            overlay,
        },
    }
    % `shell-escape' feature needs to be enabled so
    % image externalization works "automatically"
    \tikzexternalize[
        % only externalize pictures which are explicitly named
        only named=true,
        % set a path here, to where the pictures and plots should be externalized
        prefix=Pics/pgf-export/,
%        % uncomment me to force image externalization
%        % (in case you didn't change anything in the `tikzpicture' environments
%        % itself which would lead to an externalization, too
%        force remake=true,
    ]
    % define a command to set the bounding box
    \newcommand*{\UseAsBB}{
        \useasboundingbox
            % adjust the `shift' values to the bounding box
            % does include all stuff
            ([xshift=-15mm] current axis.below south west)
            rectangle
            ([shift={(18mm,7mm)}] current axis.north east);
    }
\begin{document}
\begin{figure}
        \centering
    \subfloat[bla][Bla]{%
        % set a name of the picture
        \tikzsetnextfilename{curve_plot}
        \begin{tikzpicture}[
            BB style,
        ]
            \begin{axis}[
                % use the style here
                    bla bla style,
                    %
                % list all stuff that is different in the plot here
                    ymin=-1e-3,
                    ymax=1e-3,
                    ylabel={Bar 1},
            ]
                \addplot[red, samples = 100] {1e-3*x};
            \end{axis}
            % use defined command to set the bounding box
            \UseAsBB
        \end{tikzpicture}
    }%
        \qquad
    \subfloat[blub][Blub]{%
        % set a name of the picture
        \tikzsetnextfilename{contour_plot}
        \begin{tikzpicture}[
            BB style,
        ]
            \begin{axis}[
                % use the style here
                    bla bla style,
                    %
                % list all stuff that is different in the plot here
                    ymin=0,
                    ymax=1,
                    point meta min=0,
                    point meta max=2.5,
                    colormap/viridis,
                    colorbar,
            ]
                \addplot3 [surf,shader=interp] {exp(x)};
            \end{axis}
            % use defined command to set the bounding box
            \UseAsBB
        \end{tikzpicture}
    }
    \caption{This is the main caption.}
        \label{fig:cont}
\end{figure}
\end{document}

image showing the result of above (edited) code

  • Thanks Stefan, I didn't make myself clear. But I really need to put these figures in a journal paper, so could you work out a way to use the article documentclass and figure environment ? – zljt3216 Feb 23 '16 at 1:35
  • @zljt3216, perhaps I didn't make myself clear as well in my answer. I used the standalone documentclass here, so you get "exactly" the same output as shown in the figure. If I would have used for example the article class, there would have been a lot of whitespace, which is not relevant to the question. So there is no problem to exchange to documentclass and then use the figure environment. Give it a try. – Stefan Pinnow Feb 23 '16 at 6:33
  • Thanks Stefan, I tried and it definitely worked. The only drawback is that you have to put figure label a) and b) manually because you put them in the same "tikzpicture" environment. I searched around and get another way out of this using the \useasboundingbox command. – zljt3216 Feb 24 '16 at 0:37
  • @zljt3216, after presenting your answer it seems really to be a necessity to use subfigures. But there is a much more elegant way then for "exporting" the plots. I'll show this here tomorrow morning, because today I'll not be on a computer any more having LaTeX installed. The keyword here is the tikz/pgfplots library external. See you tomorrow. – Stefan Pinnow Feb 24 '16 at 6:44
  • Stefan (seems I cannot @ you), it takes me some time to understand your answer. But one more question is that your new solution is embedded in the article class. This works for simple cases, like the MWE. But in fact, my contour plot used in my paper is really large with lots of data, so it is impossible to put the contour plot in the article and compile them together. Instead, I would have to first compile these figures independently and output as an pdf file and import them in the article. I am not sure if your new solution can be modified to that way ? – zljt3216 Feb 29 '16 at 5:13
0

A "not elegant" way to do this is using \useasboundingbox command. In this way, I have to manually tune the size of boundingbox and add some margin. The alignment is not perfect, but enough for me in this case.

The code for MWE:

\documentclass[tikz]{standalone}        
% I use standalone class, since I figure out I can output these two figures in a single pdf file and import them using \includegraphics[Page= x]{filename}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{filecontents}
\usepackage{mathtools}

\begin{document}

    \begin{tikzpicture}
        \begin{axis}[
            width = 8.7 cm,
            height = 6cm,
            scale only axis,
            xmin = -1, xmax = 1,
            ymin = -1e-3, ymax = 1e-3,
            xlabel = {Foo},
            ylabel = {Bar 1},
            ]
            \addplot[red, samples = 100] {1e-3*x};

        \end{axis}
        \useasboundingbox (0cm,0cm) rectangle (10.5 cm, 0 cm);      % manually add some margin on the right side
    \end{tikzpicture}

    \begin{tikzpicture}
        \begin{axis}[
            yshift=-2mm,
            width = 8.7 cm,
            height = 6 cm,
            scale only axis,
            view = {0}{90}, 
            xmin = -1, xmax = 1,
            ymin = 0, ymax =1,
            xlabel = {Foo},
            point meta min = 0, point meta max =2.5,
            colormap/jet,
            colorbar,
            colorbar style = {ytick = {0,0.5,1,1.5,2,2.5}},
            ]

            \addplot3[surf,shader = interp] {exp(x)};                       
        \end{axis}
        \useasboundingbox (-1.5cm,0cm) rectangle (0 cm, 0 cm);      % manually add some margin on the left side
    \end{tikzpicture}
\end{document}

The result:

enter image description here

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.