1

How can I reduce the the space between the age groups and add a male or female icon on the top from fontawesome package? Could the age-groups be in the middle of the male and female distribution? Finally, could I write inside each bar like the attached photo?

My code so far:

\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.3*\textwidth,
                height=0.4*\textheight,
                scale only axis,
                %
                xmin=0,
                xmax=100,
                ymin=-0.5,
                ymax=3.5,
                y dir=reverse,
                enlarge y limits={value=0.075,},
                %
                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,
                },
            },
        }

    \pgfplotstableread[col sep=comma, header=true]{
    agegr,menwith,menwithout,womenwith,womenwithout
      35-45,.7749,.7593,.867,.8634
    46-59,.7259,.728,.8487,.8583
    }\loadedtable

    \begin{document}
        % draw woman data on the «right» axis
        \begin{tikzpicture}
            \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{womenwith}*100},
                ] \loadedtable;
                \addplot [magenta,fill=magenta!50] table [
                    y expr =\coordindex,x expr={\thisrow{womenwithout}*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{menwith}*100},
                ] \loadedtable;
                        \addplot [cyan,fill=cyan!50] table [
                    y expr =\coordindex, x expr={\thisrow{menwithout}*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}{agegr},
                % 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}

enter image description here

  • 1
    Please provide a complete MWE, i.e. something that starts with \documentclass. Otherwise the width 0.5*\textwidth and height 0.5*\textheight are ambiguous. If you reduce the height, the bars will be closer to each other. – user121799 Aug 23 '18 at 12:08
  • 1
    I think you are searching for something similar like tex.stackexchange.com/a/297500/95441. But the rest of the questions is quite unclear. Of course you can write inside the bars, but without any specific stuff there are almost infinite possibilities ... – Stefan Pinnow Aug 23 '18 at 16:48
  • @StefanPinnow indeed it really helps! Thanks! But, still I need to add some text inside the bars and the fontawesome icons as on the updated pic. – Y_gr Aug 24 '18 at 11:14
  • As already stated, it is possible to write inside the bars, but there are plenty of ways on how to do so. But to provide the "best" way would require to know, on how many bars you want to write and if this is your real plot or just a part of it. – Stefan Pinnow Aug 25 '18 at 16:44
  • @StefanPinnow I would like at the first bar to add text b and on the second one text a for every age category. – Y_gr Aug 27 '18 at 9:32
1

As I have already written in the comment below the question most of the stuff you want to have can be found in the answer https://tex.stackexchange.com/a/297500/95441.

So it remains to add the text nodes inside the bars and to add the two symbols from the fontawesome package. Regarding the first can be done by storing the nodes near coords as nodes and later, i.e. outside the axis environments, use them to add the texts to them by using \foreach loops.

Regarding the later I think you have now all at hand to solve this problem yourself. (In my opinion this is totally superfluous, because it is already written "man" and "woman" inside the corresponding axis.)

% used PGFPlots v1.16
\documentclass[10pt]{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
   \pgfplotsset{
        % 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.3*\textwidth,
            height=0.2*\textheight,
            scale only axis,
            %
            xmin=0,
            xmax=100,
            ymin=-0.5,
            ymax=1.5,
            y dir=reverse,
            %
            xbar,
            axis x line=left,
            xtick align=outside,
            %
            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,
            % 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'
            nodes near coords style={
                font=\scriptsize,
                color=black,
                % store the `nodes near coords' as nodes
                name=node-\plotnum-\coordindex,
                /pgf/number format/fixed,
            },
        },
    }

    \pgfplotstableread[col sep=comma, header=true]{
        agegr,menwith,menwithout,womenwith,womenwithout
        35-45,.7749,.7593,.867,.8634
        46-59,.7259,.728,.8487,.8583
    }\loadedtable
    % store the number of data rows in a variable (for later use)
    \pgfplotstablegetrowsof{\loadedtable}
        \pgfmathsetmacro{\NoOfRows}{\pgfplotsretval-1}
\begin{document}
    % draw woman data on the «right» axis
    \begin{tikzpicture}
        \begin{axis}[
            pyramid axis style,
            name=women,
            %
            % add here the additional key-values which are unique to this axis
            axis y line*=left,
            ytick=\empty,
        ]
            \addplot [magenta,fill=magenta!50] table [
                y expr =\coordindex,x expr={\thisrow{womenwith}*100},
            ] \loadedtable;

            \addplot [magenta,fill=magenta!50] table [
                y expr =\coordindex,x expr={\thisrow{womenwithout}*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,
            name=men,
            %
            % where should this axis be plotted
            at={(women.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{menwith}*100},
            ] \loadedtable;
                    \addplot [cyan,fill=cyan!50] table [
                y expr =\coordindex, x expr={\thisrow{menwithout}*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={(women.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}{agegr},
            % 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;

        \end{axis}

        % add the text to the corresponding bars using the stored nodes of
        % the `nodes near coords'
        \foreach \j in {0,...,\NoOfRows} {
            \node [anchor=west,white] at (node-0-\j -| women.west)
                {text a}
            ;
        }
        \foreach \j in {0,...,\NoOfRows} {
            \node [anchor=east,white] at (node-1-\j -| men.east)
                {text b}
            ;
        }

    \end{tikzpicture}
\end{document}

image showing the cropped result of above code

  • Where are the man and the woman in your image :-))? +1. – Sebastiano Aug 27 '18 at 19:46
  • @Sebastiano, directly above the x-axis line ... – Stefan Pinnow Aug 27 '18 at 20:11
  • @Sebastiano, I hoped that it was a joke, but I was not 100% sure. So everything is fine ;) – Stefan Pinnow Aug 27 '18 at 20:16
  • @y_gr, did my answer help you to solve your question? – Stefan Pinnow Aug 30 '18 at 16:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.