2

I'm trying to plot a population pyramid using code based upon barplot that I've found here, however I'm having problems setting the values for the left axis (no numbers after the decimal point) and the y-axis is missing.

enter image description here

See original picture here

Does anyone have any ideas?

Here's the data:

pop.F<-c(0.537717667361149, 0.514712848921534, 0.537717073399189, 0.557084545268768, 
0.567834397004932, 0.582139298825445, 0.565957418909337, 0.586423112026536, 
0.587410059280687, 0.602473037729535, 0.596951974181498, 0.595324094329212, 
0.594376818092194, 0.582963584503263, 0.591416648023927, 0.604261422088911, 
0.567883789565167, 0.594503659844329, 0.469344234910119, 0.501841457211355, 
0.491217852325057, 0.490726173434756, 0.464565125135902, 0.493308069660213, 
0.522676581503902, 0.512085654241981, 0.536695926786982, 0.57145121599885, 
0.597089551756897, 0.60072309822413, 0.576708534734466, 0.577187793080901, 
0.576849827784843, 0.601365414017059, 0.623847536527997, 0.670070277869142, 
0.71956647333944, 0.722278976001524, 0.75496827807844, 0.78962490535034, 
0.740987864729483, 0.747682754143878, 0.78430364088942, 0.777897375927852, 
0.763466595545233, 0.801284460136153, 0.804158302613309, 0.782873919284743, 
0.776571715204978, 0.7673806142982, 0.769488669611802, 0.745459310984175, 
0.75373054535289, 0.744182776087168, 0.750360310528986, 0.729454007339541, 
0.689579510122758, 0.72112674182783, 0.657885627799077, 0.701900533545608, 
0.609234874649551, 0.601879472579112, 0.490294075981452, 0.509829319380846, 
0.472809338780224, 0.408395901499169, 0.421004544811214, 0.423042901901428, 
0.438408047449248, 0.399887799175123, 0.438507231574244, 0.440978729860945, 
0.427452056121215, 0.419429561424577, 0.452336733763731, 0.404481012960218, 
0.434546565963827, 0.446080357845563, 0.410747413201042, 0.383562796680424, 
0.371210553112415, 0.34346911715667, 0.334810735560917, 0.332167763120316, 
0.286944801119168, 0.292472860880887, 0.227121939115669, 0.209988381061869, 
0.184553378699683, 0.134753648607438, 0.10541234272905, 0.0736824465640457, 
0.0509363814623246, 0.0446850619000161, 0.0333505481741151, 0.0310597851463593, 
0.023990120152714, 0.0141279042905305, 0.00948655889980178, 0.00961761668483217, 
0.013647879592119)
pop.M<-c(0.573498351502067, 0.559292850391096, 0.587177401716395, 0.589887770190093, 
0.588632714462086, 0.582799990453668, 0.572319898687705, 0.639253707765031, 
0.615297152575117, 0.62753885496394, 0.627469805867318, 0.628316755817131, 
0.614195396078444, 0.625263144405424, 0.62820756554879, 0.642486348714843, 
0.635222563161176, 0.642247362242945, 0.546223088863744, 0.540921786539692, 
0.523715690842238, 0.516831976375647, 0.548392273363241, 0.538983708721224, 
0.539523158138436, 0.530272770738305, 0.569871408826156, 0.593560846001209, 
0.590887010106061, 0.60584831135686, 0.560921833539479, 0.589613005894475, 
0.591717250134999, 0.589201280552838, 0.660506618318706, 0.62325995550515, 
0.710516465510622, 0.750103418376381, 0.781971429033322, 0.763383864636709, 
0.793191548506482, 0.792852871082944, 0.807731860489672, 0.843721081070541, 
0.845288495908646, 0.87871594444754, 0.818215398802191, 0.814267973371801, 
0.796261000366516, 0.755578833361873, 0.76948171414485, 0.781161207873239, 
0.77068819475473, 0.769438354921705, 0.754416212846491, 0.762661772386676, 
0.707131620789663, 0.759594671926447, 0.71205784820271, 0.700131003325457, 
0.687487888906007, 0.62393685492915, 0.566039884964112, 0.464182047253528, 
0.477693083338275, 0.449349375282603, 0.391897602217956, 0.434015766764133, 
0.399268447612815, 0.401161345456143, 0.402684670450875, 0.389145826602956, 
0.354706513557138, 0.37697109209312, 0.327112697365322, 0.332857584899843, 
0.321479371558876, 0.32529563106868, 0.299304941717048, 0.252199941189773, 
0.242782004172793, 0.209119927808453, 0.191656734030685, 0.167093640871562, 
0.134584318985325, 0.121112109833509, 0.0849468834353985, 0.0750695671482072, 
0.0644671239198456, 0.0470356270239876, 0.029820556702351, 0.0242847650917391, 
0.0126581954114024, 0.0104516881602133, 0.00627681510522309, 
0.00898725190805402, 0.00384592156266383, 0.00409269066014978, 
0.00233983745005404, 0.00125801049286461, 0.00188512556114115)

Here's the code:

    agelabels<-c("0","","","","","5","","","","","10","","","","","15","","","","","20",
         "","","","","25","","","","","30","","","","","35","","","","","40",
         "","","","","45","","","","","50","","","","","55","","","","","60",
         "","","","","65","","","","","70","","","","","75","","","","","80",
         "","","","","85","","","","","90","","","","","95","","","","","100")



pyramide <- function(data,laxis,raxis) {
  par(cex=0.8)
  a<-as.character(x$A); m<-x$m; f<-x$f
  ff<- -m
  ll<- -laxis
  op<-par(mfrow=c(1,2),omi=c(0,0,0,0),ps=18,xaxt="s",cex=0.8)

  par(mar=c(4,2,3,1.5))

  barplot(ff,
          horiz=T,main="Hommes",
          space=0,
          col="grey",
          xlim=c(min(ll),0),
          axes=F,
          axisnames=F,
          cex.axis =0.7,
          xaxt="n")

  axis(1,
       at=ll,
       labels=formatC(laxis,format="d"),
       cex.axis =0.7)

  par(mar=c(4,2,3,2), xaxt="s")

  barplot(f,
          horiz=T,
          main="Femmes",
          space=0,col="grey",
          xlim=c(0,max(raxis)),
          axes=T,axisnames=T,
          cex.axis =0.7)

  axis(2,
       at=c(1:NROW(a))-0.5,
       labels=formatC(a,format="s"),
       pos=-2,
       las=1,tcl=0,
       lty=0,
       cex.axis =0.9)
  par(op)
}

ages <- agelabels
l <-c(seq(1,0,by=-0.2))
r <-c(seq(0,1,by=0.2))
x <- data.frame(A<-ages, m<-pop.M, f<-pop.F)

pyramide(x,l,r)
Thomas
  • 43,637
  • 12
  • 109
  • 140
user2568648
  • 3,001
  • 8
  • 35
  • 52
  • In `axis(1, ...` change the format to `"fg"` and in `axis(2, ...` use `line=.5` instead of `pos=-2`. Anyway, your function uses objects from the global environment instead of the data provided! – shadow Aug 01 '13 at 11:12
  • Thanks @shadow, I now have the following result : Is there a way to add a ".0" to the 1 and the 0 on the left axis (or take them off the right axis) - just to have both axis exactly the same ? – user2568648 Aug 01 '13 at 12:17
  • To get one digit, use `format(..., digits=1)` – shadow Aug 01 '13 at 12:26
  • There is a simple solution using `ggplot2` [here](http://stackoverflow.com/questions/31897329/population-pyramid-plot-with-ggplot2-and-dplyr-instead-of-plyr). – rafa.pereira Jun 10 '16 at 17:36

1 Answers1

4

Here's a simplification of your code that should do the trick (and fixes some references to global objects):

pyramide <- function(data,laxis,raxis) {
  a <- as.character(data$A)
  m<-data$m
  f<-data$f
  ff<- -m

  par(mai=c(1,1,1,.2))
  layout(matrix(1:2,nrow=1))
  barplot(ff,
          horiz=T,main="Hommes",
          space=0,
          col="grey",
          xlim=c(-1,0),
          axes=F,
          axisnames=F,
          cex.axis =0.7,
          xaxt="n", yaxt="n")
  axis(1,
       at=-laxis,
       labels=sprintf("%1.1f",laxis),
       cex.axis =0.7)

  par(mai=c(1,.3,1,1))
  barplot(f,
          horiz=T,
          main="Femmes",
          space=0,col="grey",
          xlim=c(0,1),
          axes=F,axisnames=F,
          cex.axis =0.7)
  axis(1,
       at=laxis,
       labels=sprintf("%1.1f",laxis),
       cex.axis =0.7)
  axis(2,
       at=as.numeric(a),
       labels=a,
       las=1,tcl=0,
       lty=0,
       cex.axis =0.5)
}

ages <- agelabels
l <-seq(1,0,by=-0.2)
r <-seq(0,1,by=0.2)
x <- data.frame(A=ages, m=pop.M, f=pop.F)

pyramide(x,l,r)

enter image description here

Thomas
  • 43,637
  • 12
  • 109
  • 140
  • Nice. I guess that the "Hommes" x-axis should also run from 0.0 to 1.0 (right to left), instead of from -0.0 to -1.0. So, l=-1*seq(1,0,by=-0.2) ? – CnrL Aug 01 '13 at 12:38
  • @Thomas Thanks. Would it be possible to add a line to the barplot to represent a second data series? Something using lines() - I've tried calling the 1st barplot a1 and doing lines(x=a1, y=ff) but nothing is plotted. – user2568648 Aug 01 '13 at 12:59
  • @user2568648 In this code I use `layout` which basically draws the left plot then starts over and draws the right plot. If you want to add anything to the left plot, you should add it to the function before the right-hand `barplot` is called. Anything after the function finishes drawing will get added to the right-hand plot only. – Thomas Aug 01 '13 at 13:05