Creating beautiful charts in chinese with ggplot2

An example with Chile-China-World trade (or 智利和中国以及世界的贸易)

Update Apr 10, 2017: There can be some problems to load XLConnect in OS X El Capitan and newer versions with a fresh R setup. If you have problems run these lines in terminal:

sudo Rscript -e 'install.packages("rJava", repos="http://rforge.net", type="source")';
sudo ln -f -s $(/usr/libexec/java_home)/jre/lib/server/libjvm.dylib /usr/local/lib

Update Jan 17, 2017: Ruilong Xu (徐瑞龙) warned me that 商務處智利中國 is 商务处智利中国 in traditional characters. Thanks for the correction,Ruilong! I still don't have 2016's official trade numbers,sorry。I also moved to an open typography to write in simplified chinese and I added some ggplot2 v2.2 new features。

Before we start

My chinese skills are poor and biased. I did learn during my internship and I continue to study while I can translate "last year our exports were 19,000 USD million" but I don't know all the colors.

I will use this dataset and for the example and you can use any chinese font you want. In this example I used Adobe Heiti but now I use Noto Sans CJK SC from Google. If you are in Mainland this zip file contains Google's Noto Sans for japanese, korean, simplified chinese and traditional chinese characters.

Initial setup

These are the necessary libraries and I did read directly from the xlsx file before defining levels, labels and colors.

library(XLConnect)
library(ggplot2)
library(RColorBrewer)
library(scales)
library(plyr)
library(forcats)

file = "../../stats/trade_chile_china/trade_data_chile_china.xlsx"

data = readWorksheetFromFile(file, sheet = "Sheet1", region = "A3:K13", header = TRUE)
data2 = readWorksheetFromFile(file, sheet = "Sheet1", region = "A17:F27", header = TRUE)
data3 = readWorksheetFromFile(file, sheet = "Sheet1", region = "A30:C35", header = TRUE)
data4 = readWorksheetFromFile(file, sheet = "Sheet1", region = "A39:E59", header = TRUE)
data5 = readWorksheetFromFile(file, sheet = "Sheet1", region = "A62:G72", header = TRUE)
data6 = readWorksheetFromFile(file, sheet = "Sheet1", region = "A75:C125", header = TRUE)

data = as.data.frame(data)
data2 = as.data.frame(data2)
data3 = as.data.frame(data3)
data3$country = factor(data3$country, levels = c("china","usa","eu","japan","korea"), labels = c("中国","美国","欧盟","日本","朝鲜"))
data4 = as.data.frame(data4)
data4$product = factor(data4$product, levels = c("copper","others"), labels = c("铜","木浆, 水果, 鱒屬和等产品"))
data4 = ddply(data4, .(year), transform, pos = cumsum(percentage) - (0.5 * percentage))
data4 = ddply(data4, .(year), transform, pos2 = cumsum(exports) - (0.5 * exports))
data5 = as.data.frame(data5)
data6 = as.data.frame(data6)
data6$product = factor(data6$product, levels=c("fruits","processedfoods","bottledwine","salmon","forestryandfurniture"), labels=c("水果","再制","瓶装酒","鱒屬","林业和木家具"))

brewer.pal(8, "Paired")
[1] "#A6CEE3" "#1F78B4" "#B2DF8A" "#33A02C" "#FB9A99" "#E31A1C" "#FDBF6F"
[8] "#FF7F00"
cbPalette = c("#1F78B4", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#556b2f", "#D55E00", "#CC79A7")
cbPalette2 = c("#4169e1", "#d68a59","#556b2f", "#FB9A99", "#33A02C")
cbPalette3 = c("#F0E442", "#56B4E9")

The charts

Here are different charts that I did create during my internship. These charts are actually "updated" as we still don't have 2016 official trade reports.

I will show how to use the new subtitles functionality in ggplot2 v2.2.0.

g1 = ggplot() + 
  geom_bar(aes(y = percentage, x = country, fill = country), data = data3, stat="identity") + 
  scale_fill_manual(values=cbPalette2) + 
  geom_text(data=data3, aes(x = country, y = (percentage + 2), label = paste0(percentage,"%")), colour="black", family="Noto Sans CJK SC", size = 4) + 
  scale_y_continuous(breaks=seq(0,40,5), labels = dollar_format(suffix = "%", prefix = "")) + expand_limits(y=c(0,25)) + 
  labs(x="",y="百分数") + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  theme(legend.position="none", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("2015年领先的出口市场",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), 
        text=element_text(size=18, family="Noto Sans CJK SC"), 
        axis.text.x=element_text(colour="black"))
g1

plot of chunk ggplot2_chinese_g1

g2 = ggplot() + 
  geom_bar(aes(y = pcentexports, x = year, fill = "pcentexports"), data = data5, stat="identity") + 
  scale_fill_manual(values="#4169e1") + 
  geom_text(data=data5, aes(x = year, y = pcentexports +2, label = paste0(pcentexports,"%")), colour="black", family="Noto Sans CJK SC", size = 4) + 
  scale_x_continuous(breaks=seq(2006,2015,1)) + scale_y_continuous(breaks=seq(0,25,5), labels = dollar_format(suffix = "%", prefix = "")) + 
  expand_limits(y=c(0,25)) + labs(x="年",y="百分数")  + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  theme(legend.position="none", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("出口中国的产品的结构",
           subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC"))
g2

plot of chunk ggplot2_chinese_g2

g3 = ggplot() + 
  geom_bar(aes(y = pcentimports, x = year, fill = "pcentimports"), data = data5, stat="identity") + 
  scale_fill_manual(values="#000080") + 
  geom_text(data=data5, aes(x = year, y = pcentimports +2, label = paste0(pcentimports,"%")), colour="black", family="Noto Sans CJK SC", size = 4) + 
  scale_x_continuous(breaks=seq(2006,2015,1)) + 
  scale_y_continuous(breaks=seq(0,25,5), labels = dollar_format(suffix = "%", prefix = "")) + 
  expand_limits(y=c(0,25)) + labs(x="年",y="百分数") + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  theme(legend.position="none", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("进口中国的产品的结构",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC"))
g3

plot of chunk ggplot2_chinese_g3

g4 = ggplot() + 
  geom_bar(aes(y = percentage, x = year, fill = fct_rev(product)), data = data4, stat="identity") + 
  scale_fill_manual(values=cbPalette3) + geom_text(data=data4, aes(x = year, y = pos, label = paste0(percentage,"%")), colour="black", family="Noto Sans CJK SC", size = 4) + 
  scale_x_continuous(breaks=seq(2006,2015,1)) + 
  scale_y_continuous(labels = dollar_format(suffix = "%", prefix = "")) + 
  labs(x="年", y="百分数")  + theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("出口中国结构 (%)",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC"))
g4

plot of chunk ggplot2_chinese_g4

g5 = ggplot() + 
  geom_bar(aes(y = exports, x = year, fill = fct_rev(product)), data = data4, stat="identity") + 
  scale_fill_manual(values=cbPalette3) + geom_text(data=data4, aes(x = year, y = pos2, label = exports), colour="black", family="Noto Sans CJK SC", size = 4) + 
  scale_x_continuous(breaks=seq(2006,2015,1)) + 
  labs(x="年", y="百万美元") + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("出口中国结构 ($)",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC"))
g5

plot of chunk ggplot2_chinese_g5

g6 = ggplot() + 
  geom_area(aes(y = exports, x = year, fill = fct_rev(product)), data = data6, stat="identity") + 
  xlab("年") + ylab("百万美元") + 
  scale_x_continuous(breaks=seq(2000,2015,3)) + 
  scale_y_continuous(breaks=seq(0,1600,400)) + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  scale_fill_brewer(palette="Paired") + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("无铜矿或造纸木材出口中国",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC"))
g6

plot of chunk ggplot2_chinese_g6

g7 = ggplot() + 
  geom_line(aes(y = exportscc, x = year, colour = "exportscc"), size=1.5, data = data, stat="identity") + 
  geom_line(aes(y = importscc, x = year, colour = "importscc"), size=1.5, data = data, stat="identity") + 
  xlab("年") + ylab("百万美元") + 
  scale_x_continuous(breaks=seq(2000,2015,3)) + 
  scale_y_continuous(breaks=seq(0,20000,5000)) + 
  expand_limits(y=c(5000,20000)) + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  scale_color_manual(labels = c("出口的产品", "进口产品"), values = c("#4169e1", "#000080")) + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("商业智利-中国",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC")) + guides(col = guide_legend(nrow = 2))
g7

plot of chunk ggplot2_chinese_g7

g8 = ggplot() + 
  geom_line(aes(y = exportscusa, x = year, colour = "exportscusa"), size=1.5, data = data, stat="identity") + 
  geom_line(aes(y = importscusa, x = year, colour = "importscusa"), size=1.5, data = data, stat="identity") + 
  xlab("年") + ylab("百万美元") + 
  scale_x_continuous(breaks=seq(2000,2015,3)) + 
  scale_y_continuous(breaks=seq(0,20000,5000)) + 
  expand_limits(y=c(5000,20000)) + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  scale_color_manual(labels = c("出口的产品", "进口产品"), values = c("#a0522d", "#E18942")) + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("商业智利-美国",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC")) + 
  guides(col = guide_legend(nrow = 2))
g8

plot of chunk ggplot2_chinese_g8

g9 = ggplot() + 
  geom_line(aes(y = exportsceu, x = year, colour = "exportsceu"), size=1.5, data = data, stat="identity") + 
  geom_line(aes(y = importsceu, x = year, colour = "importsceu"), size=1.5, data = data, stat="identity") + 
  xlab("年") + ylab("百万美元") + 
  scale_x_continuous(breaks=seq(2000,2015,3)) + 
  scale_y_continuous(breaks=seq(0,20000,5000)) + 
  expand_limits(y=c(5000,20000)) + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  scale_color_manual(labels = c("出口的产品", "进口产品"), values = c("#556b2f", "#2f556b")) + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("商业智利-欧盟",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC")) + 
  guides(col = guide_legend(nrow = 2))
g9

plot of chunk ggplot2_chinese_g9

g10 = ggplot() + 
  geom_line(aes(y = bccc, x = year, colour = "bccc"), size=1.5, data = data2, stat="identity") + 
  geom_line(aes(y = bccw, x = year, colour = "bccw"), size=1.5, data = data2, stat="identity") + 
  xlab("年") + ylab("百万美元") + 
  scale_x_continuous(breaks=seq(2000,2015,3)) + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  scale_color_manual(labels = c("淨出口中国的产品", "淨出口人间的产品"), values = c("#4169e1", "#FF43A4")) + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("淨出口中国和人间",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC")) + guides(col = guide_legend(nrow = 2))
g10

plot of chunk ggplot2_chinese_g10

g11 = ggplot() + 
  geom_line(aes(y = bccusa, x = year, colour = "bccusa"), size=1.5, data = data2, stat="identity") + 
  geom_line(aes(y = bccw, x = year, colour = "bccw"), size=1.5, data = data2, stat="identity") +
  xlab("年") + ylab("百万美元") + 
  scale_x_continuous(breaks=seq(2000,2015,3)) + scale_y_continuous(breaks=seq(-10000,25000,5000)) + 
  expand_limits(y=c(-10000,25000)) + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) +
  scale_color_manual(labels = c("淨出口美国的产品", "淨出口人间的产品"), values = c("#d68a59", "#FF43A4")) +
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("淨出口美国和人间",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC")) + guides(col = guide_legend(nrow = 2))
g11

plot of chunk ggplot2_chinese_g11

g12 = ggplot() + 
  geom_line(aes(y = bcceu, x = year, colour = "bcceu"), size=1.5, data = data2, stat="identity") + 
  geom_line(aes(y = bccw, x = year, colour = "bccw"), size=1.5, data = data2, stat="identity") + 
  xlab("年") + ylab("百万美元") + 
  scale_x_continuous(breaks=seq(2000,2015,3)) + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  scale_color_manual(labels = c("淨出口人间的产品", "淨出口欧盟的产品"), values = c("#FF43A4", "#556b2f"), guide = guide_legend(reverse=TRUE)) + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("淨出口欧盟和人间",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC")) + 
  guides(col = guide_legend(nrow = 2))
g12

plot of chunk ggplot2_chinese_g12

g13 = ggplot() + 
  geom_line(aes(y = exportscc, x = year, colour = "exportscc"), size=1.5, data = data, stat="identity") + 
  geom_line(aes(y = exportscusa, x = year, colour = "exportscusa"), size=1.5, data = data, stat="identity") + 
  geom_line(aes(y = exportsceu, x = year, colour = "exportsceu"), size=1.5, data = data, stat="identity") + 
  xlab("年") + ylab("百万美元") +
  scale_x_continuous(breaks=seq(2000,2015,3)) + scale_y_continuous(breaks=seq(0,20000,5000)) + expand_limits(y=c(5000,20000)) + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  scale_color_manual(labels = c("中国(第一贸易合作伙伴)出口智利的产品", "美国(第二贸易合作伙伴)出口智利的产品", "欧盟(第三贸易合作伙伴)出口智利的产品"), values = c("#4169e1", "#d68a59","#556b2f")) + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("出口中国,美国和欧盟的产品",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC")) + 
  guides(col = guide_legend(nrow = 3))
g13

plot of chunk ggplot2_chinese_g13

g14 = ggplot() + 
  geom_line(aes(y = importscc, x = year, colour = "importscc"), size=1.5, data = data, stat="identity") + 
  geom_line(aes(y = importscusa, x = year, colour = "importscusa"), size=1.5, data = data, stat="identity") + 
  geom_line(aes(y = importsceu, x = year, colour = "importsceu"), size=1.5, data = data, stat="identity") + 
  xlab("年") + ylab("百万美元") + 
  scale_x_continuous(breaks=seq(2000,2015,3)) + 
  scale_y_continuous(breaks=seq(4000,20000,4000)) + 
  expand_limits(y=c(4000,20000)) + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  scale_color_manual(labels = c("中国(第一贸易合作伙伴)进口智利的产品", "美国(第二贸易合作伙伴)进口智利的产品", "欧盟(第三贸易合作伙伴)进口智利的产品"), values = c("#4169e1", "#d68a59","#556b2f")) + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("从中国,美国和欧盟进口产品",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC")) + 
  guides(col = guide_legend(nrow = 3))
g14

plot of chunk ggplot2_chinese_g14

g15 = ggplot() + 
  geom_line(aes(y = bccc, x = year, colour = "bccc"), size=1.5, data = data2, stat="identity") + 
  geom_line(aes(y = bccusa, x = year, colour = "bccusa"), size=1.5, data = data2, stat="identity") + 
  geom_line(aes(y = bcceu, x = year, colour = "bcceu"), size=1.5, data = data2, stat="identity") + 
  xlab("年") + ylab("百万美元") + 
  scale_x_continuous(breaks=seq(2000,2015,3)) + 
  scale_y_continuous(breaks=seq(-10000,15000,5000)) + 
  expand_limits(y=c(-10000,15000)) + 
  theme(panel.background = element_rect(fill="white"), panel.grid = element_line(colour="white")) + 
  scale_color_manual(labels = c("中国(第一贸易合作伙伴)淨出口智利的产品", "美国(第二贸易合作伙伴)淨出口智利的产品", "欧盟(第三贸易合作伙伴)淨出口智利的产品"), values = c("#4169e1", "#d68a59","#556b2f")) + 
  theme(legend.position="bottom", legend.direction="horizontal", legend.title = element_blank(), axis.line.x = element_line(size=0.5), axis.line.y = element_line(size=0.5)) + 
  ggtitle("淨出口中国,美国和欧盟进口产品",
          subtitle = "消息灵通人士: 智利海关总署, 智利中央银行 & 商务处智利中国") + 
  theme(plot.title=element_text(size=20, family="Noto Sans CJK SC"), plot.subtitle=element_text(size=12, family="Noto Sans CJK SC"), text=element_text(size=18, family="Noto Sans CJK SC")) + 
  guides(col = guide_legend(nrow = 3))
g15

plot of chunk ggplot2_chinese_g15