如何将坐标附近的节点应用到单个条形图/单个图?

如何将坐标附近的节点应用到单个条形图/单个图?

阅读后美丽的人口金字塔问题,我受到启发,对图表进行“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单个栏目/单个图?”。

话虽如此,以下是针对您的四个问题的快速答案:

  1. nodes near coords您可以在选项中指定\addplot [...],而不是在\begin{axis}[...]选项中指定。这样,它将仅适用于该图。
  2. 如何在绘图中添加零线?
  3. 您可以将表中的相关条目从 更改25--29\bfseries 25--29
  4. 设置enlarge y limits={abs=1}, enlarge x limits=false(或类似)。

相关内容