# Scale tikzpicture with axis and xbar to the “real” textwidth

So, whenever I create a xbar plot with long labels it happens to me that the tikzpicture is scaled too wide because (I guess) textwidth only applies to the axis but not the labels. So I thought I substract the width of the longest label from textwidth, but then the width is too small. My question is:

1. how can I get the "real" textwidth?
2. if possible, how can I get that automatically without entering the longest label by hand

\documentclass[12pt,a4paper]{scrreprt}

\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{filecontents}
\usepackage{lipsum}

\begin{filecontents*}{species.dat}
species,no_dbh
Fagus sylvatica,0.746478873239437
Pinus sylvestris,0.633802816901408
Quercus petraea,0.563380281690141
Pseudotsuga menziesii,0.126760563380282
\end{filecontents*}

\begin{document}
\lipsum[1-1]

\begin{figure}[hpbt]
\centering
\begin{tikzpicture}
\begin{axis}[
xbar,
x tick label style={font=\footnotesize},
y tick label style={font=\scriptsize},
height=5cm,
width=\textwidth,
xmajorgrids=true,
major grid style={dotted, very thick},
axis x line*=bottom,
axis y line*=none,
bar width=5pt,
symbolic y coords={Fagus sylvatica,Pinus sylvestris,Quercus petraea,Pseudotsuga menziesii},
ytick=data,
xticklabel={\pgfmathparse{\tick*100} pgfmathprintnumber{\pgfmathresult}\%},
y dir=reverse,
enlarge y limits=0.2,
xmax=0.85,
xmin=0,
nodes near coords,
every node near coord/.append style={anchor=west,font=\scriptsize},
nodes near coords align={horizontal},
point meta=x*100,
nodes near coords=\pgfmathprintnumber{\pgfplotspointmeta}\%
]
\end{axis}
\end{tikzpicture}
\caption{Tree species probability}
\end{figure}

\lipsum[2-2]
\end{document}


My solution is too use width=\textwidth-width("Pseudotsuga menziesii") but then it's scalled too small.

• How's it too wide? I tried to compile your code but did not get the "too wide" point. – L. F. Feb 21 at 10:26
• @L.F. I am sorry, I implemented my solution which makes it too small. I removed it. – Felix Phl Feb 21 at 10:33
• OK. But I think the result is ok with width=\textwidth-width("Pseudotsuga menziesii"). – L. F. Feb 21 at 10:38

Instead of extracting the largest label and measure its width with the correct font settings, you can first typeset the whole diagram in a savebox and then calculate the requires axes width to get the complete graph \textwidth wide. Then typeset it again with that width setting. This has the drawback that the computation effort is doubled, but this should not be a problem on modern computers, but only on very large documents.

Very large diagram code might be better places into an own TEX file and read using \input, otherwise the argument to \adjustwidth will need a lot of memory.

\documentclass[12pt,a4paper]{scrreprt}

\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{filecontents}
\usepackage{lipsum}

\begin{filecontents*}{species.dat}
species,no_dbh
Fagus sylvatica,0.746478873239437
Pinus sylvestris,0.633802816901408
Quercus petraea,0.563380281690141
Pseudotsuga menziesii,0.126760563380282
\end{filecontents*}

\newlength\WIDTH
\newbox\mybox

\setlength\WIDTH{\textwidth}
\savebox\mybox{#1}%
\pgfmathsetlength\WIDTH{2\textwidth-\wd\mybox}
#1%
}

\begin{document}
\lipsum[1-1]

\begin{figure}[hpbt]
\centering
\begin{tikzpicture}
\begin{axis}[
xbar,
x tick label style={font=\footnotesize},
y tick label style={font=\scriptsize},
height=5cm,
width=\WIDTH,
xmajorgrids=true,
major grid style={dotted, very thick},
axis x line*=bottom,
axis y line*=none,
bar width=5pt,
symbolic y coords={Fagus sylvatica,Pinus sylvestris,Quercus petraea,Pseudotsuga menziesii},
ytick=data,
xticklabel={\pgfmathparse{\tick*100}\pgfmathprintnumber{\pgfmathresult}\%},
y dir=reverse,
enlarge y limits=0.2,
xmax=0.85,
xmin=0,
nodes near coords,
every node near coord/.append style={anchor=west,font=\scriptsize},
nodes near coords align={horizontal},
point meta=x*100,
nodes near coords=\pgfmathprintnumber{\pgfplotspointmeta}\%
]