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}
5
  • Do you have any code you've attempted to use so far? If so, please add it.
    – Null
    Commented Feb 22, 2016 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
    Commented Feb 22, 2016 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. Commented Feb 22, 2016 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. Commented Feb 22, 2016 at 17:17
  • Thanks, @StefanPinnow, I edit the original post and give a MWE.
    – zljt3216
    Commented Feb 22, 2016 at 20:03

2 Answers 2

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

10
  • 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
    Commented Feb 23, 2016 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. Commented Feb 23, 2016 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
    Commented Feb 24, 2016 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. Commented Feb 24, 2016 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
    Commented Feb 29, 2016 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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .