# How can I implement a simple PGF Plots Bar Chart environment?

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}


# 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}

% 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}
{%
\BODY
\datatable
% Use \datatable for plot data
\begin{tikzpicture}
\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

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}

% 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
% Use \datatable for plot data
\begin{tikzpicture}
\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}