How do I apply nodes near coords to a single bar / to a single plot?
That's a lot of questions in a single post. This site works best if you ask about a single issue per post, preferably in such a way that other people with similar problems have a chance of finding the question. I would suggest that for each question in your post, you open a new issue where you try to generalise and whittle down the problem in such a way that it is "googleable". For example, your first question could be phrased as "How do I apply nodes near coords
to a single bar / to a single plot?".
That said, here are quick answers for your four questions:
- You can specify the
nodes near coords
in the\addplot [...]
options instead of in the\begin{axis}[...]
options. That way, it will only apply for that plot. - See How can I add a zero line to a plot?
- You can change the relevant entry in the table from
25--29
to\bfseries 25--29
. - Set
enlarge y limits={abs=1}, enlarge x limits=false
(or similar).
Related videos on Youtube
Michael S Taylor
Updated on August 01, 2022Comments
-
Michael S Taylor over 1 year
After reading the pretty population pyramid question, I was inspired to "Tufte-ify" the graph to remove redunancy and clutter (and to become more familiar with
pgfplots
).I modified the code from leonardo cedar's answer to the population pyramid question. For learning purposes, I decided to highlight one data point that I thought was interesting. With one exception, the proportion of females is larger than males beginning with the 25-29 year age group. Using an idea taken from here. I highlighted the male and female bars and added the percentage of each gender. The result is shown below; overall, I'm pleased with the result but not with the way I obtained it.
I have four questions. If I should split them into separate posts, please let me know.
1) How can I automatically associate the precentage with the chosen bar? In my MWE, the position of the two percentages at the of each red bar is hard coded, using
\node [color=white] at (\xcenter+3.8cm,-6.05cm) {\scriptsize 4.34\%}; % Females \node [color=white] at (\xcenter-3.65cm,-6.05cm) {\scriptsize 3.87\%}; % Males
Leonardo's code had:
nodes near coords = {\pgfmathprintnumber\pgfplotspointmeta\%}, every node near coord/.append style={rotate = 0, anchor = east, font=\scriptsize, color=black},
which placed the percentage for every bar (for the males, in this case). I know I can change the anchor to
west
to get the percentages plotted inside the bar. Can I change this to plot the precent for just one bar? Or is there another way?2) Is there a way to automatically determine the height of the graph area occupied by the bars? I hard coded a thin black line at 0% on the x-axis to provide a visual center dividing males and females. I played around with the coordinates to position it. I would like to determine the height programmatically. (In this case, the black line does not extend all the way to the top because it would cover the uppermost data point. I'm not worried about that overall.)
3) Is it possible to bold the y tick label for just the chosen data point, in this case the 25-29 year olds? I have no idea where to begin.
4) How can I shift the x- and y-axes closer to the bars? I have no idea where to begin.
MWE. Other suggestions for improvement are welcome:
\documentclass[10pt]{article} \usepackage{pgfplots} \usepackage{pgfplotstable} \usepackage{filecontents} \pgfplotsset{% discard if not/.style 2 args={ x filter/.code={ \edef\tempa{\thisrow{#1}} \edef\tempb{#2} \ifx\tempa\tempb \else \def\pgfmathresult{inf} \fi } } } \begin{document} \begin{filecontents}{data.csv} {age},{male},{female} +100,0,4 95--99,3,6 90--94,10,16 85--89,43,57 80--84,103,111 75--79,175,224 70--74,274,322 65--69,421,427 60--64,514,524 55--59,578,606 50--54,732,785 45--49,885,911 40--44,1044,1120 35--39,1192,1289 30--34,1315,1306 25--29,1214,1362 20--24,1360,1336 15--19,1471,1406 10--14,1495,1446 5--9,1375,1351 0--4,1325,1257 \end{filecontents} \pgfplotstableread[col sep=comma, header=true]{data.csv}{\datatable} \begin{center} \begin{tikzpicture} \edef\xcenter{0cm}% from John Kormylo's answer \pgfplotsset{major grid style={thin, white}} \begin{axis}[ %Female name=popaxis, scale only axis, xbar, /pgf/bar shift=0pt, xmin=0, xmax=5, width=0.5*\textwidth, height= 0.5*\textheight, y dir = reverse, xticklabel= {\pgfmathprintnumber\tick\%}, axis x line=left, axis y line=none, enlarge x limits = {value=0.15,upper}, axis line style={white}, clip=false, xmajorticks=true, every x tick/.style={color={white}}, grid=major, axis on top ] \addplot[white,fill=black!30] table[y expr =\coordindex, x expr={\thisrow{female}/31395*100}, col sep=comma] {data.csv};%total pop = 31395 \addplot[white,fill=red!50!black, discard if not ={male}{1214}] table[y expr =\coordindex, x expr={\thisrow{female}/31395*100}, col sep=comma] {data.csv}; \pgfplotstablegetrowsof{\datatable} \pgfmathsetmacro{\lastrow}{\pgfplotsretval} \node[xshift=-3cm,yshift=7cm,align=center] at (axis cs:0,\lastrow) {Male}; \node[xshift= 3cm,yshift=7cm,align=center] at (axis cs:0,\lastrow) {Female}; \node[xshift= -8.5cm,yshift=7cm,align=left] at (axis cs:0,\lastrow) {Age Group\\(years)}; % hard-coded precentage for females 25-29. \node [color=white] at (\xcenter+3.8cm,-6.05cm) {\scriptsize 4.34\%}; \end{axis} % \begin{axis}[ % Male at={(popaxis.north west)},anchor=north east, scale only axis, xbar, /pgf/bar shift=0pt, xmin = 0, xmax = 5, width=0.5*\textwidth, height= 0.5*\textheight, x dir=reverse, y dir=reverse, % Leonardo's code that print's all precentages for males. I just want one. % nodes near coords = {\pgfmathprintnumber\pgfplotspointmeta\%}, % every node near coord/.append style={rotate = 0, anchor = west, font=\scriptsize, color=black}, xticklabel= {\pgfmathprintnumber\tick\%}, axis x line=left, axis y line*=left, ytick = data, yticklabels from table = {\datatable}{age}, ytick align=center, ytick pos=left, enlarge x limits = {value=0.15,upper}, axis line style={white}, every x tick/.style={color=white}, every y tick/.style={color=white}, xmajorgrids=true, axis on top ] \addplot[white,fill=black!30] table[y expr =\coordindex, x expr={\thisrow{male}/31395*100}, col sep=comma] {data.csv}; \addplot+[white,fill=red!50!black, discard if not = {male}{1214}] table[y expr =\coordindex, x expr={\thisrow{male}/31395*100}, col sep=comma] {data.csv}; % Hard coded precentage for males, 25-29. \node [color=white] at (\xcenter-3.65cm,-6.05cm) {\scriptsize 3.87\%}; \end{axis} % Hard-coded center axis \draw [color=black, line width=0.1pt] (0,0.63) -- (0,8.6cm); \end{tikzpicture} \end{center} \end{document}
Here is the resulting graph:
-
Michael S Taylor over 9 yearsIs it too late to remove some of my questions? I ask because if I only include the first question, then the helpful answers supplied by @Jake for 2-4 won't have context.