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
3

1 Answer 1

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}

You must log in to answer this question.

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