Creating a complex chart in R

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.

Advertisements

1 thought on “Creating a complex chart in R”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s