阅读后美丽的人口金字塔问题,我受到启发,对图表进行“Tufte-ify”,以消除冗余和混乱(并变得更加熟悉pgfplots
)。
我修改了 leonardo cedar 对人口金字塔问题的回答中的代码。出于学习目的,我决定突出显示一个我认为有趣的数据点。除了一个例外,从 25-29 岁年龄组开始,女性的比例大于男性。使用来自这里。我突出显示了男性和女性条形图,并添加了每个性别的百分比。结果如下所示;总体而言,我对结果感到满意,但对获得结果的方式不满意。
我有四个问题。如果我应该将它们分成不同的帖子,请告诉我。
1) 如何自动将百分比与所选条形图关联起来?在我的 MWE 中,每个红色条形图的两个百分比的位置是硬编码的,使用
\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
莱昂纳多的代码有:
nodes near coords = {\pgfmathprintnumber\pgfplotspointmeta\%},
every node near coord/.append style={rotate = 0, anchor = east, font=\scriptsize, color=black},
它将百分比放在每个条形中(在本例中是男性)。我知道我可以更改锚点以west
将百分比绘制在条形内。我可以将其更改为仅绘制一个条形的百分比吗?或者还有其他方法吗?
2) 有没有办法自动确定条形图所占图形区域的高度?我在 x 轴的 0% 处硬编码了一条细黑线,以提供区分男性和女性的视觉中心。我尝试了各种坐标来定位它。我想以编程方式确定高度。(在这种情况下,黑线不会一直延伸到顶部,因为它会覆盖最上面的数据点。总体而言,我并不担心这一点。)
3) 是否可以只为选定的数据点(在本例中为 25-29 岁)加粗 y 刻度标签?我不知道从哪里开始。
4) 如何将 x 轴和 y 轴移近条形图?我不知道从哪里开始。
平均能量损失。欢迎提出其他改进建议:
\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}
结果图如下:
答案1
一篇帖子里有很多问题。如果您每篇帖子只问一个问题,这个网站的效果会最好,最好是这样的方式,让有类似问题的人有机会找到这个问题。我建议,对于您帖子中的每个问题,您都打开一个新问题,尝试将问题概括并缩小,以便“可谷歌搜索”。例如,您的第一个问题可以表述为“我如何申请nodes near coords
单个栏目/单个图?”。
话虽如此,以下是针对您的四个问题的快速答案:
nodes near coords
您可以在选项中指定\addplot [...]
,而不是在\begin{axis}[...]
选项中指定。这样,它将仅适用于该图。- 看如何在绘图中添加零线?
- 您可以将表中的相关条目从 更改
25--29
为\bfseries 25--29
。 - 设置
enlarge y limits={abs=1}, enlarge x limits=false
(或类似)。