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.

Using log-scale for bar charts is probably not a good idea due to the lack of a true zero.

However, given skewed data, there doesn't seem to be much alternative ... otherwise smaller values get too compressed for comparison.

Using xbar in pgfplots, my idea was to use log scale for the x-axis, but indicate the zero issue using a discontinuity in the axis.

Code:

\documentclass{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{semilogxaxis}[
 axis x discontinuity=crunch,
 log basis x=2,
 log origin=infty,
 y post scale=0.4,
 legend style={at={(0.5,1.1)},anchor=south},
 legend columns=4,
 ytick={one,two,eight,sixty-four},
 symbolic y coords={one,two,eight,sixty-four},
 bar width=7pt,
 enlarge y limits=0.5 
]

\addplot+[xbar] coordinates {(1,one)};
\addlegendentry{one}

\addplot+[xbar] coordinates {(2,two)};
\addlegendentry{two}

\addplot+[xbar] coordinates {(8,eight)};
\addlegendentry{eight}

\addplot+[xbar] coordinates {(64,sixty-four)};
\addlegendentry{sixty-four}

\end{semilogxaxis}
\end{tikzpicture}
\end{document}

Output:

enter image description here

The output looks fine (with a little further non-MWE tweaking), but I receive two error messages upon build:

Errors:

! Missing number, treated as zero.
<to be read again> 
          \pgfplots@data@scale@trafo@SHIFT@x 
l.30 \end{semilogxaxis}

A number should have been here; I inserted `0'.
(If you can't figure out why I needed to see a number,
look up `weird error' in the index to The TeXbook.)

! Illegal unit of measure (pt inserted).
<to be read again> 
               \pgfplots@data@scale@trafo@SHIFT@x 
l.30 \end{semilogxaxis}

I guess this is to do with the lack of a "true origin" to shift the discontinuity from on the axis. However, the output achieves what I want. Hence ...

Can anyone suggest a method to fix the error? Otherwise, how could I suppress such errors?

(I think I would also like to label the x origin with "0" if anyone had suggestions for that.)

share|improve this question
    
I would say a better alternative would be just using a scatterplot instead of a bar plot... –  Jake Nov 25 '12 at 21:17
    
In my case, there's no ordering on the secondary axis. Hence there are no Cartesian co-ordinates and, for me, scatter plots have the wrong "semantics". ... put another way, I don't have a 2D plot but a collection of 1D plots that are comparable, but not ordered. –  badroit Nov 25 '12 at 21:31
1  
this is a bug in pgfplots. I will take a note to fix it –  Christian Feuersänger Nov 27 '12 at 16:50
    
Christian, thanks for an awesome package! –  badroit Nov 28 '12 at 0:02
add comment

1 Answer

up vote 4 down vote accepted

You can use a decoration to place the axis discontinuity. The decoration in the example below is adapted from Draw the discontinuity symbol with tikz.

\documentclass{standalone}
\usepackage{pgfplots}
\pgfdeclaredecoration{discontinuity}{start}{
  \state{start}[width=0.04\pgfdecoratedinputsegmentremainingdistance-0.5\pgfdecorationsegmentlength,next state=up from center]
  {}
  \state{up from center}[width=+.5\pgfdecorationsegmentlength, next state=big down]
  {
    \pgfpathlineto{\pgfpointorigin}
    \pgfpathlineto{\pgfqpoint{.25\pgfdecorationsegmentlength}{\pgfdecorationsegmentamplitude}}
  }
  \state{big down}[next state=center finish]
  {
    \pgfpathlineto{\pgfqpoint{.25\pgfdecorationsegmentlength}{-\pgfdecorationsegmentamplitude}}
  }
  \state{center finish}[width=0.5\pgfdecoratedinputsegmentremainingdistance, next state=do nothing]{
    \pgfpathlineto{\pgfpointorigin}
    \pgfpathlineto{\pgfpointdecoratedinputsegmentlast}
  }
  \state{do nothing}[width=\pgfdecorationsegmentlength,next state=do nothing]{
    \pgfpathlineto{\pgfpointdecoratedinputsegmentlast}
  }
  \state{final}
  {
    \pgfpathlineto{\pgfpointdecoratedpathlast}
  }
}

\begin{document}
\begin{tikzpicture}
\begin{semilogxaxis}[
 log basis x=2,
 log origin=infty,
 y=0.5cm,
 legend style={at={(0.5,1.1)},anchor=south},
 legend columns=-1,
 ytick={one,two,eight,sixty-four},
 symbolic y coords={one,two,eight,sixty-four},
 bar width=7pt,
 enlarge y limits=0.5,
 enlarge x limits={0.15},
 separate axis lines,
every outer x axis line/.append style=
{decoration={discontinuity, segment length=3mm}, decorate},
]

\addplot+[xbar] coordinates {(1,one)};
\addlegendentry{one}

\addplot+[xbar] coordinates {(2,two)};
\addlegendentry{two}

\addplot+[xbar] coordinates {(8,eight)};
\addlegendentry{eight}

\addplot+[xbar] coordinates {(64,sixty-four)};
\addlegendentry{sixty-four}

\end{semilogxaxis}
\end{tikzpicture}
\end{document}

In my eyes, a better alternative to a discontinuity symbol on a logarithmic axis (which really doesn't make any sense mathematically) would be to use a scatter plot. To show that the data is essentially one-dimensional, you could use a y grid:

\documentclass[border=5mm]{standalone}
\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{semilogxaxis}[
 log basis x=2,
 log origin=infty,
 y=0.5cm,
 legend style={at={(0.5,1.1)},anchor=south},
 legend columns=-1,
 ytick={one,two,eight,sixty-four},
 symbolic y coords={one,two,eight,sixty-four},
 bar width=7pt,
 enlarge y limits=0.5,
 enlarge x limits={0.15},
 ymajorgrids=true
]

\addplot coordinates {(1,one)};
\addlegendentry{one}

\addplot coordinates {(2,two)};
\addlegendentry{two}

\addplot coordinates {(8,eight)};
\addlegendentry{eight}

\addplot coordinates {(64,sixty-four)};
\addlegendentry{sixty-four}

\end{semilogxaxis}
\end{tikzpicture}
\end{document}
share|improve this answer
    
Many thanks! (The y-grid is a nice alternative: it discourages looking for an arbitrary trend across the grid/series. However, in my view, the logarithmic y-grid suffers the exact same problem as for a bar plot, or indeed any plot with 0 in its interval.) –  badroit Nov 28 '12 at 0:14
add comment

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.