There are many different ways to create a chart in R. Now I am going to show an easy method with the layout command through a hypothetical example to build a pretty complex chart like this.

In our example we would like to visualise the number of sales of 4 different products and the profit in our 10 best selling offices. Here are the data we would like to plot:

> data Total Product A Product B Product C Product D Profit New York 787 340 160 161 126 83000 Bangkok 751 356 206 127 62 62000 Paris 743 408 155 93 87 85000 El Paso 696 259 209 108 120 78000 Sidney 696 270 190 176 60 47000 Shanghai 654 238 198 141 77 41000 Auckland 643 191 168 148 136 39000 Beijing 630 235 117 160 118 76000 Houston 570 199 175 99 97 51000 Amsterdam 531 180 95 170 86 55000

In the first column is the number of the sales of the 4 products, in the second, third, fourth and fifth columns the number of the sales of the products one by one and in the last column is the profit in the different offices in USD (hypothetical data).

Before the plot we have to calculate some additional things.

To the added line we need the cumulative proportion of the total number of sales and the maximum value of the cumulative proportion to the axis according to the line. In our example we have other offices as well, and the number of sales in all of our offices is 10000.

> data$CumProp<-cumsum(data$Total)/total > maxCumProp<-max(data$CumProp)

In order to expand this line from the bottom to the top of the chart we have to correct it’s values with the ratio of the maximal number of sales and the maximal original value of the calculated cumulative proportion.

> data$CumProp<-data$CumProp*(max(data$Total)/max(data$CumProp))

We calculate the coordinates the labels of the columns (in the middle of the parts of the columns) and edit the labels: instead of the absolute number of sales we represent the proportion of sales of each product in percentage. We also define the text of the legend and the chosen colors.

> labels<-sapply(data[,2:5], function(x) paste(round(100*(x/data[,1]), 0), "%", sep=" ") ) > labelcoor<-cbind(data[,2]/2, + data[,2]+data[,3]/2, + data[,2]+data[,3]+data[,4]/2, + data[,2]+data[,3]+data[,4]+data[,5]/2) > > legend<-c("Product A", "Product B", "Product C", "Product D") > > colors<-c("#CC941399", "#005A9452", "#C383ED99", "#00B8C199", "#FF000099")

Now we can start to create our chart.

We will save our chart as a png. First we define the size of it and some graphical parameters. The background will be transparent, so we can use our chart for example in a ppt with a background color.

> png("~/Chart.png", width=2000, height=1000) > par(xpd=TRUE, bg="transparent", mar=c(5,4.5,3.2,3))

With the layout command we divide the chart.

> layout(matrix(c(1,1,1,2,3,4,0,5,0,6,7,0), 4, 3, byrow = TRUE), width=c(0.6,4.6,1.4), + heights=c(0.4,2,0.5,0.7), respect = TRUE)

That means that the chart will be divided to 12 parts. To the first row comes the first chart (it will be the title), to the second row the 2., 3. and 4. chart (left axis name, stacked column chart, legend), to the third row only the 5. and to the last the 6. and 7. The width and height of the parts are determined here too.

1 | 1 | 1 |

2 | 3 | 4 |

0 | 5 | 0 |

6 | 7 | 0 |

After specifying which chart where to come, we can start plotting.

> #1 > plot.new() > title("Top 10 Sales Offices", line=-4, cex.main=5, font.main=2) > #2 > plot.new() > text(0.9, 0.5, "Absolut Number of Sales", cex=3, srt = 90)

By the 3. chart we define the axises separate, because we want different scales. The axis names are located to the two other parts of the plot, there we can specify them more precisely.

> #3 > chart<-barplot(t(as.matrix(data[,2:5])), axes=FALSE, border="transparent", mar=c(0,0,0,0), + beside=FALSE, col=colors[1:4], axisnames=FALSE, space=0.3:0.3) > lines(chart, data$CumProp, lwd=2) > points(chart, data$CumProp, pch=16) > axis(4, at=seq(from=0, to=max(data[,1]), by=max(data[,1])/4), + lab=paste(round(100*seq(from=0, to=maxCumProp, by=maxCumProp/4),2), "%", sep=""), + las=2, cex.axis=2.4) > axis(2, at=seq(from=0, to=max(data[,1]), by=max(data[,1])/4), + lab=round(seq(from=0, to=max(data[,1]), by=max(data[,1])/4),0), + las=2, cex.axis=2.4) > text(chart+0.1, labelcoor, labels, cex=2.9) > text(c(0.7, chart[2:length(chart)]), data$Total+25, data$Total, cex=2.9) > #4 > plot.new() > text(0.03, 0.5, "Cumulative Proportion of Sales", cex=3, srt = 270) > legend(0.15,0.3, legend, fill=colors[1:4], border="transparent", cex=4, bty="n") > #5 > plot.new() > text(seq(from=0.02, to=0.98, by=0.96/9), t(rep(1, length(rownames(data)))), rownames(data), cex=3, srt = 30) > #6 > plot.new() > text(x=0.9, y=0.5, "Profit (USD)", cex=3, srt=90) > #7 > profit<-plot(data$Profit, type="b", axes=FALSE, col=colors[5], lwd=4, xlab="", ylab="") > text(seq(from=1, to=(20), by=1), data$Profit+7000, data$Profit, cex=2.3) > axis(2, at=seq(from=35000, to=100000, by=100000/4), + lab=round(seq(from=35000, to=100000, by=100000/4),0), + las=2, cex.axis=2.4) > # > dev.off()

Learn more about creating plots in R here and here.

## One thought on “Creating a complex chart in R”