我正在尝试绘制人口金字塔图形。
我写了这个 MWE。
\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\begin{document}
\pgfplotstableread[col sep=comma]{
age,man,woman
+100 years,0,4
95 - 99 years,3,6
90 - 94 years,10,16
85 - 89 years,43,57
80 - 84 years,103,111
75 - 79 years,175,224
70 - 74 years,274,322
65 - 69 years,421,427
60 - 64 years,514,524
55 - 59 years,578,606
50 - 54 years,732,785
45 - 49 years,885,911
40 - 44 years,1044,1120
35 - 39 years,1192,1289
30 - 34 years,1315,1306
25 - 29 years,1214,1362
20 - 24 years,1360,1336
15 - 19 years,1471,1406
10 - 14 years,1495,1446
5 - 9 years,1375,1351
0 - 4 years,1325,1257
}\loadedtable
\begin{tikzpicture}
\begin{axis}[
width =\textwidth,
height = 0.6*\textheight,
enlarge x limits=0.6,
xbar = 0pt,
xmin = -5,
xmax = 5,
y dir = reverse,
nodes near coords,
bar width=8pt,
bar shift=0pt,
axis x line= left,
nodes near coords = {\pgfmathprintnumber\pgfplotspointmeta\%},
every node near coord/.append style={font=\scriptsize, color=black},
xticklabel= {\pgfmathprintnumber\tick\%},
symbolic y coords={+100 years,95 - 99 years,90 - 94 years,85 - 89 years,80 - 84 years,75 - 79 years,70 - 74 years,65 - 69 years,60 - 64 years,55 - 59 years,50 - 54 years,45 - 49 years,40 - 44 years,35 - 39 years,30 - 34 years,25 - 29 years,20 - 24 years,15 - 19 years,10 - 14 years,5 - 9 years,0 - 4 years},
ytick={+100 years,95 - 99 years,90 - 94 years,85 - 89 years,80 - 84 years,75 - 79 years,70 - 74 years,65 - 69 years,60 - 64 years,55 - 59 years,50 - 54 years,45 - 49 years,40 - 44 years,35 - 39 years,30 - 34 years,25 - 29 years,20 - 24 years,15 - 19 years,10 - 14 years,5 - 9 years,0 - 4 years}
]
\addplot [fill = cyan!50] table[y=age,x expr={-\thisrow{man}/31395*100}] \loadedtable;%31395 is the total population
\addlegendentry{Man}
\addplot [fill = magenta!50] table[y=age,x expr={\thisrow{woman}/31395*100}] \loadedtable;%31395 is the total population
\addlegendentry{Woman}
\end{axis}
\end{tikzpicture}
\end{document}
但结果却是一张丑陋的图表:
我怎样才能改进它以获得这样的效果?
答案1
想要漂亮需要付出很多努力!
\documentclass{standalone}
\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\usepackage{pgfplotstable}
\usepackage{wasysym}
\begin{document}
\pgfplotstableread[col sep=comma]{
age,man,woman
+100 years,0,4
95 - 99 years,3,6
90 - 94 years,10,16
85 - 89 years,43,57
80 - 84 years,103,111
75 - 79 years,175,224
70 - 74 years,274,322
65 - 69 years,421,427
60 - 64 years,514,524
55 - 59 years,578,606
50 - 54 years,732,785
45 - 49 years,885,911
40 - 44 years,1044,1120
35 - 39 years,1192,1289
30 - 34 years,1315,1306
25 - 29 years,1214,1362
20 - 24 years,1360,1336
15 - 19 years,1471,1406
10 - 14 years,1495,1446
5 - 9 years,1375,1351
0 - 4 years,1325,1257
}\loadedtable
\newlength{\dy}\setlength{\dy}{\baselineskip}
\newlength{\dx}\setlength{\dx}{0.007em}
\newlength{\temp}
\pgfplotstablegetrowsof{\loadedtable}
\pgfmathparse{\pgfplotsretval-1}
\edef\rows{\pgfmathresult}
% compute total for percentages
\setlength{\temp}{0pt}
\foreach \y in {0,1,...,\rows}{%
\pgfplotstablegetelem{\y}{man}\of\loadedtable
\global\advance\temp by \pgfplotsretval pt
\pgfplotstablegetelem{\y}{woman}\of\loadedtable
\global\advance\temp by \pgfplotsretval pt
}
\pgfmathparse{0.01\temp}
\edef\total{\pgfmathresult}
\noindent\begin{tikzpicture}
\node at (0,2\dy) {Population Pyramid - 2010};
\node[below,text=Navy] at (-8em,0) {\huge\mars};
\node[below,text=HotPink] at (8em,0) {\huge\venus};
\foreach \y in {0,1,...,\rows}{%
\pgfplotstablegetelem{\y}{age}\of\loadedtable
\node[left] at (-19em,-\y\dy) {\strut\pgfplotsretval};
\pgfplotstablegetelem{\y}{man}\of\loadedtable
\node[left] at (-15em,-\y\dy) {\strut\pgfplotsretval};
\node[left,fill=Navy,text width=\pgfplotsretval\dx,text height=.8\dy,inner sep=0]
at (0,-\y\dy+0.1\dy) {};
\pgfmathparse{\pgfplotsretval/\total}
\pgfmathprintnumberto[fixed,precision=2]{\pgfmathresult}{\per}
\node[left] at (-\pgfplotsretval\dx,-\y\dy) {\small\strut\per\%};
\pgfplotstablegetelem{\y}{woman}\of\loadedtable
\node[left] at (17em,-\y\dy) {\strut\pgfplotsretval};
\node[right,fill=HotPink,text width=\pgfplotsretval\dx,text height=.8\dy,inner sep=0]
at (0,-\y\dy+0.1\dy) {};
\pgfmathparse{\pgfplotsretval/\total}
\pgfmathprintnumberto[fixed,precision=2]{\pgfmathresult}{\per}
\node[right] at (\pgfplotsretval\dx,-\y\dy) {\small\strut\per\%};
}
\node[left] at (-3em,-\rows\dy-.9\dy) {Man};
\node[left,fill=Navy,text width=2em,text height=.8\dy,inner sep=0]
at (-1mm,-\rows\dy-.9\dy) {};
\node[right,fill=HotPink,text width=2em,text height=.8\dy,inner sep=0]
at (+1mm,-\rows\dy-.9\dy) {};
\node[right] at (3em,-\rows\dy-.9\dy) {Woman};
\end{tikzpicture}
\end{document}
您可以通过调整字体来调整大小,或者使用 \resizebox 来更精确地调整大小。
答案2
这个看起来好多了 = )
\documentclass[10pt]{article}
\usepackage{pgfplots}\pgfplotsset{compat=1.10}
\usepackage{pgfplotstable}
\usepackage{lmodern}
\usepackage{wasysym}
\begin{document}
\pgfplotstableread[col sep=comma, header=true]{
age,man,woman
+100 years,0,4
95 - 99 years,3,6
90 - 94 years,10,16
85 - 89 years,43,57
80 - 84 years,103,111
75 - 79 years,175,224
70 - 74 years,274,322
65 - 69 years,421,427
60 - 64 years,514,524
55 - 59 years,578,606
50 - 54 years,732,785
45 - 49 years,885,911
40 - 44 years,1044,1120
35 - 39 years,1192,1289
30 - 34 years,1315,1306
25 - 29 years,1214,1362
20 - 24 years,1360,1336
15 - 19 years,1471,1406
10 - 14 years,1495,1446
5 - 9 years,1375,1351
0 - 4 years,1325,1257
}\loadedtable
\begin{tikzpicture}
\begin{axis}[
name=popaxis,
scale only axis,
xbar,
xmin=0,
xmax=5,
%xbar=2pt,
%xlabel={\%},
width=0.5*\textwidth, height= 0.5*\textheight,
y dir = reverse,
nodes near coords = {\pgfmathprintnumber\pgfplotspointmeta\%},
every node near coord/.append style={font=\scriptsize, color=black},
xticklabel= {\pgfmathprintnumber\tick\%},
y tick label style={text width=3cm,align=center},
axis x line=left,
axis y line=none,
%
enlarge x limits = {value=0.15,upper},
axis line style={-},
clip=false
]
\addplot[magenta,fill=magenta!50] table[y expr =\coordindex, x expr={\thisrow{woman}/31395*100}] \loadedtable;%total pop = 31395
%
\pgfplotstablegetrowsof{\loadedtable}
\pgfmathsetmacro{\lastrow}{\pgfplotsretval-1}
\node[xshift=-1.5cm,yshift=-0.5cm,align=center] at (axis cs:0,\lastrow) {\textcolor{cyan}{\huge\mars} Man};
\node[xshift= 1.5cm,yshift=-0.5cm,align=center] at (axis cs:0,\lastrow) {\textcolor{magenta}{\huge\venus} Woman};
\node[xshift= 0.0cm,yshift=-2.0cm,align=center] at (axis cs:0,\lastrow) {\%};
%
\end{axis}
\begin{axis}[
at={(popaxis.north west)},anchor=north east, %xshift=-3cm,
scale only axis,
xbar = 0,
xmin = 0,
xmax = 5,
width=0.5*\textwidth,
height= 0.5*\textheight,
x dir=reverse,
y dir=reverse,
nodes near coords = {\pgfmathprintnumber\pgfplotspointmeta\%},
every node near coord/.append style={rotate = 0, anchor = east, font=\scriptsize, color=black},
xticklabel= {\pgfmathprintnumber\tick\%},
axis x line=left,
axis y line*=left,
%
ytick = data,
yticklabels from table = {\loadedtable}{age},
ytick align=center,
ytick pos=left,
enlarge x limits = {value=0.15,upper},
axis line style={-}
]
\addplot[cyan,fill=cyan!50] table[y expr =\coordindex, x expr={\thisrow{man}/31395*100}] \loadedtable; %total pop = 31395
\end{axis}
\end{tikzpicture}
\end{document}