Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

This question led to a new package:
tikzscale

When I try to scale a plot with: width=\textwidth there is some horizontal space between the start/end of the plot and the start/end of the margins, see this example:

\documentclass[10pt,a4paper]{report}
\usepackage[latin1]{inputenc}
\usepackage{palatino}
\usepackage{color}
\usepackage{pgfplots}
\usepgfplotslibrary{dateplot} 
\pgfplotsset{compat=1.3}

\begin{document}
\setlength{\parindent}{0ex}

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\vspace*{2ex}

\begin{tikzpicture}
\begin{axis}[
height=5cm,
width=\textwidth,
grid=both,
minor x tick num=4,
minor y tick num=4,
major tick length=0.15cm,
minor tick length=0.075cm,
tick style={semithick,color=black}, 
date coordinates in=x,
xticklabel=\day.\month.,
date ZERO=2009-09-02,% <- improves precision!
]

\addplot[color = black, mark=diamond*] coordinates {
(2009-08-07, 98)
(2009-08-09, 92)
(2009-08-12, 94)
(2009-08-15, 87)
(2009-08-19, 82)
(2009-08-26, 65)
(2009-08-29, 54)
(2009-09-02, 31)
};
\end{axis}
\end{tikzpicture}

\vspace*{2ex}Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

\end{document}
share|improve this question
add comment

3 Answers

up vote 25 down vote accepted

As Stefan said, the width and height of the plot are only approximate. Stefan's solution is very nice in that the plot area including labels, titles, legends, and so on, will take up exactly the width of the text area. However, the text in your plot will be scaled, which may or may not be acceptable to you.

A different approach would be to you use the scale only axis option, which specifies that the width and height only apply to the axis itself, not the labels, titles etc. In conjunction with \begin{tikzpicture}[trim axis left], you can make the axis take up the exact width of the text, with the ticklabels extending into the left margin:

Alternatively, you can manually correct the width of the plot for the width of the ticklabels. If you set scale only axis, width=\textwidth-\widthof{<longest ticklabel>}-<ticklabel offset>, the overall plot width will be exactly the width of the text. By default, the offset of the ticklabels is achieved with an inner sep, which introduces whitespace also on the outside of the label. To avoid this, you can set yticklabel style={inner sep=0pt, align=right, xshift=-0.1cm}.

Here's the code for the two approaches:

First solution, ticklabels protruding into margin

\documentclass[10pt,a4paper]{report}
\usepackage[latin1]{inputenc}
\usepackage{palatino}
\usepackage{lipsum}
\usepackage{pgfplots}
\usepgfplotslibrary{dateplot} 

\begin{document}
\setlength{\parindent}{0ex}

\lipsum[1]\vspace*{2ex}

\begin{tikzpicture}[trim axis left]
\begin{axis}[
scale only axis, % The height and width argument only apply to the actual axis
height=5cm,
width=\textwidth,
grid=both,
max space between ticks=40, % To control the number of major ticks
minor x tick num=4,
minor y tick num=4,
major tick length=0.15cm,
minor tick length=0.075cm,
tick style={semithick,color=black}, 
date coordinates in=x,
xticklabel=\day.\month.
]

\addplot[color = black, mark=diamond*] coordinates {
(2009-08-07, 98)
(2009-08-09, 92)
(2009-08-12, 94)
(2009-08-15, 87)
(2009-08-19, 82)
(2009-08-26, 65)
(2009-08-29, 54)
(2009-09-02, 31)
};
\end{axis}
\end{tikzpicture}

\vspace*{2ex}\lipsum[2]

\end{document}

Second solution, overall plot width exactly text width

\documentclass[10pt,a4paper]{report}
\usepackage[latin1]{inputenc}
\usepackage{palatino}
\usepackage{lipsum}
\usepackage{pgfplots}
\usepgfplotslibrary{dateplot} 

\begin{document}
\setlength{\parindent}{0ex}

\lipsum[1]\vspace*{2ex}

\begin{tikzpicture}
\begin{axis}[
scale only axis, % The height and width argument only apply to the actual axis
height=5cm,
width=\textwidth-\widthof{100}-0.1cm, % \textwidth minus width of longest label text minus label offset
yticklabel style={align=right,inner sep=0pt,xshift=-0.1cm}, % No inner sep, to remove whitespace on left, manually offset by given distance
grid=both,
max space between ticks=40, % To control the number of major ticks
minor x tick num=4,
minor y tick num=4,
major tick length=0.15cm,
minor tick length=0.075cm,
tick style={semithick,color=black}, 
date coordinates in=x,
xticklabel=\day.\month.
]

\addplot[color = black, mark=diamond*] coordinates {
(2009-08-07, 98)
(2009-08-09, 92)
(2009-08-12, 94)
(2009-08-15, 87)
(2009-08-19, 82)
(2009-08-26, 65)
(2009-08-29, 54)
(2009-09-02, 31)
};
\end{axis}
\end{tikzpicture}

\vspace*{2ex}\lipsum[2]

\end{document}
share|improve this answer
    
Thanks! I'am using the first solution now, ist perfect! –  Benjamin Nov 28 '11 at 13:31
add comment

Since pgfplots doesn't use the exact space, you could make it fit using \resizebox of graphicx:

\resizebox{\textwidth}{!}{%
\begin{tikzpicture}%
...
\end{tikzpicture}}

resized pgf plot

share|improve this answer
    
No, its about ther horizontal space to the left and right margin. The width schould be like the \textwidth but it isn't. –  Benjamin Nov 28 '11 at 7:04
    
@Benjamin The question said "some space between the start/end of the plot and the start/end of the text", that's why I thought you meant that vertical space. I'll check that soon, perhaps in the meantime there might be another answer. –  Stefan Kottwitz Nov 28 '11 at 7:17
    
@Benjamin Ok, I changed the answer. –  Stefan Kottwitz Nov 28 '11 at 8:00
    
That is what i was looking for. Thank you! –  Benjamin Nov 28 '11 at 13:30
add comment

The solutions from Stefan an Jake scale the fonts, write into the margin or require some manual tweaking. I was heading for an automatic solution, so that nothing has to be tweaked again, if the document is changed. The fonts in all plots should have the same size, so resizebox was not an option for me. As I didn't want to plot into the margins either, I came up with the following solution:

result

\documentclass{minimal}
\usepackage{lipsum}
\usepackage{pgfplots}
\usepgfplotslibrary{dateplot} 

\newsavebox{\measuredSize}
\newcommand{\resizeToWidth}[2]{%
    \pgfmathsetmacro{\pgfplotswidth}{#2}%
    \begin{lrbox}{\measuredSize}#1\end{lrbox}%
    \pgfmathsetmacro{\pgfplotswidth}{2*\pgfplotswidth-\wd\measuredSize}%
    #1%
}

\newcommand{\inputPlot}{%
    \begin{tikzpicture}
        \begin{axis}
            [
                height=5cm,
                width=\pgfplotswidth,
                yticklabel style={align=right,inner sep=0pt,xshift=-0.3em},
                grid=both,
                max space between ticks=50,
                minor x tick num=4,
                minor y tick num=4,
                tick style={semithick,color=black}, 
                date coordinates in=x,
                xticklabel=\day.\month.
            ]
            \addplot[color = black, mark=diamond*] coordinates{
                (2009-08-07, 98) (2009-08-09, 92) (2009-08-12, 94) (2009-08-15, 87) (2009-08-19, 82) (2009-08-26, 65) (2009-08-29, 54) (2009-09-02, 31)
            };
        \end{axis}
    \end{tikzpicture}%
}

\begin{document}
    \setlength{\parindent}{0ex}

    \lipsum[1]\vspace*{2ex}

    \resizeToWidth{\inputPlot}{\textwidth}

    \vspace*{2ex}\lipsum[2]
\end{document}

I normally keep my tikzpictures in separate files, which then get included as needed. The command \inputPlot reflects that. The basic idea to get the correct width is to plot the graphic twice. First, plot into some sort of virtual box and measure the width, which unfortunately is only an approximation of the width we wanted to have. Then, correct the demanded width to compensate for the approximation error to get the correct width.

In theory if there are some non-linearities in the approximation, the two lines in the middle of \resizeToWidth have to be repeated multiple times, to incrementally improve the solution. I still have to play around a bit to see, if this is really needed in practice. Of course, effectively rendering the plot multiple times does not improve the compilation speed. Changing a global state from a plot now more than once might be problematic, so don't do that.

I wonder if it might be worth creating a package, which does this scaling iteratively until the change from one iteration to the next one is below a specific error. That might also be handy for a tikzpicture without a pgfplot to get a correct scaling factor.

share|improve this answer
1  
This is a really clever approach. You might want to get in touch with Christian Feuersänger, the author of pgfplots, to turn this into a library/feature directly incorporated in the package. –  Jake May 20 '12 at 22:01
1  
Jake, I contacted Christian Feuersänger and we both agreed that this functionality would be better put into a separate package. I just uploaded this package (called tikzscale) to CTAN. After loading it, you can simply use \includegraphics[width=\textwidth]{fileContainingTikzpicture}. –  Patrick Häcker Oct 31 '12 at 14:33
1  
That's excellent! Would you mind also adding your package to the Which questions led to the creation of a new package?-list? –  Jake Oct 31 '12 at 14:37
1  
@Jake, ok, done (although the CTAN link does not work, yet, but I guess it will work after getting processed) –  Patrick Häcker Oct 31 '12 at 14:49
1  
Detail on the side: tex.stackexchange.com/questions/42114/… –  doncherry Oct 31 '12 at 17:01
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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