我如何使用 pgfplots 绘制这个人口金字塔图?

我如何使用 pgfplots 绘制这个人口金字塔图?

我正在使用这个代码并且它运行良好:如何使用 pgfplots 绘制漂亮的人口金字塔图?

但我想画出图中这样的人口金字塔。请指导我怎么做。在此处输入图片描述

答案1

我改编了您在问题中提供的链接中的代码以得到期望的结果。

因为只有 x 值有刻度线,所以需要绘制三个轴:一个用于“男人”数据,一个用于“女人”数据,一个仅用于绘制 y 数据,因为无法tick length独立设置 x 轴和 y 轴。

有关更多详细信息,请查看代码中的注释。

% done with pgfplots v1.13
\documentclass[10pt]{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
    \pgfplotsset{
        compat=1.9,
        %
        % create a style which is used for all the axis
        % this one is especially for drawing the axis plotting the y axis
        blank pyramid axis style/.style={
            width=0.5*\textwidth,
            height=0.5*\textheight,
            scale only axis,
            %
            xmin=0,
            xmax=5.5,
            ymin=-0.5,
            ymax=20,
            y dir=reverse,
            enlarge y limits={value=0.075,upper},
            %
            xbar,
            axis x line=left,
            xtick align=outside,
            %
            bar width=1,
            allow reversal of rel axis cs=false,
        },
        % this style is for the axis drawing the data
        pyramid axis style/.style={
            blank pyramid axis style,
            %
            % draw `xtick's as percent values
            xticklabel={%
                \pgfmathprintnumber\tick\%%
            },
            % don't draw any `ytick' values
            ytick=\empty,
%            % for debugging purposes draw draw data from loaded table as `ytick's
%            ytick=data,
%            yticklabels from table={\loadedtable}{age},
%            y tick label style={
%                major tick length=0pt,
%                align=center,
%                text width=12.5mm,
%                inner sep=0pt,
%                draw=red,
%                text=red,
%            },
            % just draw a line as axis lines
            axis line style={-},
            %
            % draw `nodes near coords' also in percentages
            nodes near coords={%
                \pgfmathprintnumber\pgfplotspointmeta\%%
            },
            % set the style of `nodes near coords'
            every node near coord/.append style={
                font=\scriptsize,
                color=black,
                /pgf/number format/fixed,
            },
        },
    }
\begin{document}
    \begin{tikzpicture}
        \pgfplotstableread[
            col sep=comma,
            header=true,
        ]{
            age,man,woman
            +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
        }\loadedtable
        % add a column in the table summing up the «man» and «woman» values
        % accumulatively
        % with the sum of all values one can calculate the percentages of the
        % values
        \pgfplotstablecreatecol[
            expr accum={
                round(\pgfmathaccuma) + \thisrow{man} + \thisrow{woman}
            }{0}
        ]{sum}{\loadedtable}
        % turn on `fpu' library when numbers are larger than 16384
        \tikzset{
            fpu=true,
        }
            % get the number of data rows of the loaded table
            \pgfplotstablegetrowsof{\loadedtable}
                \pgfmathsetmacro{\LastRow}{\pgfplotsretval-1}
            % now get the last entry of the «sum» column which contains the
            % sum of all «man» and «woman» values
            % (for whatever reason this doesn't seem to work; it is returned
            %  the value of the second row ...)
%            \pgfplotstablegetelem{\LastRow}{sum}\of{\loadedtable}
            \pgfplotstablegetelem{20}{sum}\of{\loadedtable}
                \pgfmathsetmacro{\Sum}{\pgfplotsretval}
        \tikzset{
            fpu=false,
        }
    % draw woman data on the «right» axis
        \begin{axis}[
            pyramid axis style,
            %
            % add here the additional key-values which are unique to this axis
            axis y line*=left,
            ytick=\empty,
            name=popaxis,
        ]
            \addplot [magenta,fill=magenta!50] table [
                y expr =\coordindex,x expr={\thisrow{woman}/\Sum*100},
            ] \loadedtable;

            \node [anchor=south] at (rel axis cs:0.25,1)
                {\textcolor{magenta}{Woman}};
        \end{axis}

    % draw man data on the «left» axis
        \begin{axis}[
            pyramid axis style,
            %
            % where should this axis be plotted
            at={(popaxis.west)},
            anchor=east,
            % shift to the left
            xshift=-12.5mm,
            %
            % add here the additional key-values which are unique to this axis
            x dir=reverse,
            every node near coord/.append style={
                anchor=east,
            },
            axis y line*=right,
        ]
            \addplot [cyan,fill=cyan!50] table [
                y expr =\coordindex, x expr={\thisrow{man}/\Sum*100},
            ] \loadedtable;

            \node [anchor=south] at (rel axis cs:0.25,1)
                {\textcolor{cyan}{Man}};
        \end{axis}

    % «dummy» axis to draw the y values
    % (the extra axis is needed because it seems that the tick length cannot
    %  be set independently for the x and y axis)
        \begin{axis}[
            blank pyramid axis style,
            %
            % where should this axis be plotted
            at={(popaxis.west)},
            anchor=east,
            xshift=-12.5mm,
            %
            % add here the additional key-values which are unique to this axis
            x dir=reverse,
            axis y line*=right,
            % don't draw `xtick's (they are already drawn with ticks)
            xtick=\empty,
            % draw `ytick's with the data from the table
            ytick=data,
            yticklabels from table={\loadedtable}{age},
            % set the style of `yticklabels'
            % (the labels should be plot centered between the axis;
            %  therefore use `align=center' and set the `text width'
            % so that
            y tick label style={
                align=center,
                inner sep=0pt,
                text width=12.5mm,
            },
            % set ticks length to zero
            major tick length=0pt,
            % make axis lines invisible
            axis line style={
                -,
                draw=none,
            },
        ]
            % add a dummy plot so that the axis ticks are drawn correctly
            \addplot [draw=none,fill=none] table [
                y expr =\coordindex, x expr={0},
            ] \loadedtable;

%            % dummy nodes to check the values of `\Sum' and `\LastRow'
%            \node [anchor=south] at (rel axis cs:0.5,1) {\pgfmathprintnumber{\Sum}};
%            \node [anchor=south] at (rel axis cs:0.75,1) {\pgfmathprintnumber{\LastRow}};
        \end{axis}
    \end{tikzpicture}
\end{document}

该图显示了上述代码的结果

相关内容