2

To the point... GLOBALIZED SHARED FORMATTING (across instances) and LOCALIZED DATA (unique to each instance)

Ideal Code

\begin{horizontalbarchart}
17,Sales
24,Marketing
31,Finance
42,Operations
\end{horizontalbarchart}

enter image description here

My Attempt

Use a combo of xparse and newenviron. Note that I am only using \pgfplotstableread to avoid using symbolic y coords, because using symbloc y coords means repeating data that is already specified in the plot data.

 \documentclass{article}
 \usepackage{fontspec}%xelatex
 \usepackage{pgfplots,pgfplotstable}
 \usepackage{newenviron}
 \usepackage{xparse}

 \pgfplotsset{horizontalbarchartpgfplotstableread/.style={
 % symbolic y coords=,% set dict of expected textual y coordinates
  axis lines*=left,
  y=1cm,% vertical spacing (define the length of a unit in the y direction )
  xbar,
  bar width=5mm,% bar thickness
  y axis line style = { opacity = 0 },
  width=.7\textwidth,
  xmajorgrids,
  xminorgrids,
  xlabel={}, % optional label below x axis but useless in global style
  xmin=0,
  xmax=100,
  point meta={x},
  nodes near coords={\pgfmathprintnumber\pgfplotspointmeta\%},% puts text (set in "point meta" key) near coordinates.
  nodes near coords align={horizontal},% alignment of "nodes near coords"
  color=orange,
  enlarge y limits={abs=10mm},% add space above and below bars
  yticklabels from table={\datatable}{1}, % necessary for pgfplotstableread data
  ytick=data,%
  }
 }
 \NewEnviron{horizontalbarchartBODY}
 {%
 % Inject BODY into pgfplotstableread
 \pgfplotstableread[col sep=comma, header=false]{
 \BODY
 \datatable
 % Use \datatable for plot data
 \begin{tikzpicture}
   \begin{axis}[horizontalbarchartpgfplotstableread]
     \addplot table [col sep=comma, y expr=\coordindex, x=0] {\datatable};
   \end{axis}
 \end{tikzpicture}
 }
\NewDocumentEnvironment{horizontalbarchart}{}{\horizontalbarchartBODY\endhorizontalbarchartBODY}{}
\begin{document}
% Insert Easy Bar Chart Environment here.
\end{document}

Goals

My custom environment horizontalbarchart creates a nice horizontal bar chart.

  • The width of every instance is set to .7\textwidth.
  • n number of items.
  • Each number in the data represents a percent.
  • Global TikZ style for axis properties
  • Bar labels (for horizontal bar charts, this means y ticks) are set dynamically from the data in each environment instance.
  • To do: Colors of the bars can be changed based on percentages
1

I used the facilities of fancyvrb to create a new environment that writes the verbatim environment content to a file (you need to preserve the line breaks because pgfplotstableread expects ^^M I think, so a simple token list will not work). At the end of the environment, I read the exported file with \pgfplotsreadtable and typeset it with tikzpicture+axis+addplot.

I am not sure if this is the best way, because there might be a way I am overlooking that does not need an auxiliary file.

Code

\documentclass{article}
\usepackage{fontspec}
\usepackage{pgfplots,pgfplotstable}
\usepackage{fancyvrb}

 \pgfplotsset{horizontalbarchartpgfplotstableread/.style={
 % symbolic y coords=,% set dict of expected textual y coordinates
  axis lines*=left,
  y=1cm,% vertical spacing (define the length of a unit in the y direction )
  xbar,
  bar width=5mm,% bar thickness
  y axis line style = { opacity = 0 },
  width=.7\textwidth,
  xmajorgrids,
  xminorgrids,
  xlabel={}, % optional label below x axis but useless in global style
  xmin=0,
  xmax=100,
  point meta={x},
  nodes near coords={\pgfmathprintnumber\pgfplotspointmeta\%},% puts text (set in "point meta" key) near coordinates.
  nodes near coords align={horizontal},% alignment of "nodes near coords"
  color=orange,
  enlarge y limits={abs=10mm},% add space above and below bars
  yticklabels from table={\datatable}{1}, % necessary for pgfplotstableread data
  ytick=data,%
  }
 }

\newenvironment{horizontalbarchart}
  {\VerbatimOut{\jobname-barchart.export}}
  {\endVerbatimOut
  % Inject BODY into pgfplotstableread
 \pgfplotstableread[col sep=comma, header=false]{\jobname-barchart.export}{\datatable}
   % Use \datatable for plot data
 \begin{tikzpicture}
   \begin{axis}[horizontalbarchartpgfplotstableread]
     \addplot table [col sep=comma, y expr=\coordindex, x=0] {\datatable};
   \end{axis}
 \end{tikzpicture}
  }%


\begin{document}

\begin{horizontalbarchart}
17,Sales
24,Marketing
31,Finance
42,Operations
\end{horizontalbarchart}

\end{document}

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.