Various examples of code to generate common plots with GGplot.

#Load the ggplot library
setwd("~/Ruben Analyse/Forskning og utvikling/GGplot examples") #css file is here

library(ggplot2)

#For å bruke custom fonts
library(extrafont) 
loadfonts(device = "win")
font_import(pattern='GARA')


Modify and set custom theme

This is how to customize an existing theme. I use this theme for remaining examples.

#Oppdatere theme bw til mitt personlige theme
theme_set(theme_bw()) #set theme to theme_bw as starting point


#Edit somoe of the parameters in the bw theme
theme_update(legend.position=c(0.9,0.8) #Default legend position is topright
,legend.background=element_blank() #No legend background
,legend.text=element_text(size=10) #Legend text size
,legend.title=element_text(size=10) #Legend title text size
,panel.grid.major = element_blank() #remove grids
,panel.grid.minor = element_blank() #remove grids
,panel.border = element_blank() #remov the panel border (inner plot area border)
,axis.line = element_line(colour = "darkgray") #Axis lines
,plot.title=element_text(hjust = 0.5,face="bold",family = "Garamond") #Settings for  title. Set font bold and center.
,plot.subtitle=element_text(hjust = 0.5,face="italic",family='Garamond') #Subtitle. italic and centered.
,axis.text.x = element_text(face="italic") #Axis labels italics
,axis.text.y = element_text(face="bold",size=8,angle = 0) #Axis labels italics
,plot.margin=unit(c(1,0.2,0.2,0), "cm")
)


Basic Scatter plot

df <- data.frame(xx=rnorm(1000,sd=0.1),yy=rnorm(1000,sd=0.1))
ggplot(df, aes(x = xx,y = yy)) +
geom_point()

Scatterplot with color mapped to value

Not a great idea but useful in some settings.

#Color mapped to value
ggplot(mtcars, aes(x = wt, y = mpg, col = disp)) +
geom_point(size=2) + scale_color_gradient(low="lightpink",high = "darkred") +
  labs(title="Mpg vs. vehicle weight and engine displacement volume")

Scatterplot with point size mapped to value

#Point size mapped to value
ggplot(mtcars, aes(x = wt, y = mpg, size = disp)) +
geom_point(color="tomato") +
    labs(title="Mpg vs. vehicle weight and engine displacement volume",x="weight")

Time series

For time series it is easiest to put the variables in a common dataframe on the same y-axis.

set.seed(6)
#Simulate two stocks (random walk)

StockA = 100
StockB = 100

StockFrame <- matrix(nrow=1000,ncol=3)

StockFrame[1,] <- c(1,100,100)

for (i in 2:1000){
StockA = StockA * 1+rnorm(1)
StockB = StockB * 1+rnorm(1)

StockFrame[i,] <- c(i,StockA,StockB)

}

StockFrame <- data.frame(StockFrame)
colnames(StockFrame) <- c("Time","StockA","StockB")

library(reshape2)

meltdf <- melt(StockFrame,id="Time")


ggplot(meltdf,aes(x=Time,y=value,colour=variable)) +
  geom_line() +
  theme(legend.title = element_blank(),legend.position = c(0.9,0.9)) +
  labs(title="Time-series example (Rebased y value)")

Annotate plots

Place lines text and more on a plot

srbankQuotes <- read.csv("http://quotes.hegnar.no/paperhistory.php?paper=SRBANK.OSE&csv_format=csv") #Grab SRbank stock price (working jan 17)

library(lubridate) #use this to easily handle dates
srbankQuotes$date <- ymd(srbankQuotes$quote_date) #Convert int to date
srbankQuotes <- srbankQuotes[srbankQuotes$date>=as.Date("2015-01-01")&srbankQuotes$date<=as.Date("2017-01-20"),] #Limit time period

ggplot(srbankQuotes,aes(x=date,y=close)) +
  geom_line(color="salmon") +
  theme(legend.title = element_blank(),legend.position = c(0.9,0.9)) +
  labs(title="SR-Bank Stock prices",subtitle="01 Jan 2015 - 20 Jan 2017, Important dates highlighted",x="",y="Price, NOK") +
  
  #Do the actual annotations
  annotate("text",x=as.Date("2016-08-10"),y=55,label="01 September 2016 \nRuben joins the bank",size=3,fontface="italic") +
  annotate("segment",x=as.Date("2016-09-01"),xend=as.Date("2016-09-01"),y=srbankQuotes$close[srbankQuotes$date=="2016-09-01"],yend=53,linetype=2) +
  annotate("text",x=as.Date("2016-10-01"),y=62,label="03 October 2016 \nMark joins the bank",size=3,fontface="italic") +
  annotate("segment",x=as.Date("2016-10-03"),xend=as.Date("2016-10-03"),y=srbankQuotes$close[srbankQuotes$date=="2016-10-03"],yend=54,linetype=2) + 
  annotate("segment",x=as.Date("2016-10-03"),xend=as.Date("2016-10-03"),y=56.5,yend=60,linetype=2) 

Scatterplot with marginal distributions

#Make dummy data, correlated variables
x <- rnorm(10000)
y <- 0.5*x+rnorm(10000,mean=1,sd=0.5)
df <- data.frame(x,y)

#Make inner plot
p <- ggplot(df, aes(x = x, y = y)) + geom_point(alpha=0.5,color="#3F681C")

#Add Marginal Histograms
p <- ggExtra::ggMarginal(p,type = "histogram",binwidth=.05,col="#2988BC",fill="#2988BC",alpha=0.8)

p

Basic barplot

This barplot plots the frequency of the variable on the y axis

set.seed(2)
Group <- sample(c("a","b","c","d","e"),prob = c(0.2,0.2,0.15,0.3,0.15),size = 1000,rep=T)
Value <- rnorm

df <- data.frame(Group)
ggplot(df,aes(x=Group,fill=Group)) + geom_bar(width = 0.6) + theme(legend.position = "none") + labs(title="Basic barplot")

Barplot with sum as height

This plot shows the hights as the group-sum of another variable.

#Generate dummy data.
set.seed(3)
Group <- sample(c("a","b","c","d","e"),size=1000,rep=T)
Value <- rnorm(1000,mean=1,sd=5)
df <- data.frame(Group,Value)



ggplot(df,aes(x=Group,fill=Group,weight=Value,hue=Group)) +
  geom_bar(width = 0.6) +
  theme(legend.position = "none") +
  labs(y="Sum of value variable",title="Barplot showing category sum for some variable")

Barplot with y variable

When the y value is allready computed, use stat=“identity”.

set.seed(2)
Group <- sample(c("a","b","c","d","e"),size=100,rep=T)
Value <- rnorm(100,mean=1,sd=20)

df <- data.frame(Group,Value)

#Calculate maximum value within each group
library(data.table)
df <- data.table(df)
dfSum <- df[,.(MaxVal=max(Value)),by=Group]

dfSum
##    Group   MaxVal
## 1:     a 35.21263
## 2:     d 43.20147
## 3:     c 34.43238
## 4:     e 41.96081
## 5:     b 41.62485
ggplot(dfSum,aes(x=Group,fill=Group,y=MaxVal)) +
  geom_bar(width = 0.6,stat="identity") + #need identity when using y value
  theme(legend.position = "none") +
  labs(title="Barplot with self-supplied y-value",y="value passed to Y axis")

Arrange bars of barplots

Arrange the bars descending or ascending according to some value in the data

set.seed(1)
Group <- sample(c("a","b","c","d","e"),size=15,rep=T)
Value <- rnorm(15,mean=1,sd=20)

df <- data.frame(Group,Value)

#Calculate maximum value within each group
library(data.table)
df <- data.table(df)
dfSum <- df[,.(MaxVal=max(Value)),by=Group]
setorder(dfSum,-MaxVal)

#Show unordered dataframe
dfSum
##    Group     MaxVal
## 1:     b  49.093068
## 2:     c  16.271869
## 3:     d   6.044469
## 4:     e  -4.789231
## 5:     a -16.838423
ggplot(dfSum,aes(x=reorder(Group,-MaxVal),fill=Group,y=MaxVal)) +
  geom_bar(width = 0.6,stat="identity") +
  theme(legend.position = "none") +
  labs(title="Barplot with sorted X-axis",y="Group maximum value")

Clustered barplot with values

Bar values plotted above bars

set.seed(1)
dat <- data.frame(Group=c('A','B','C','D','E'),
                  Var1=runif(5),
                  Var2=runif(5),
                  Var3=runif(5))

dat.melt <- melt(dat, id.vars='Group')

ggplot(dat.melt, aes(variable, value,fill = Group,label=round(value,1))) + #Label is used to put the numbers on the bars
  geom_bar(position = "dodge",stat="identity") +
  theme(legend.position = "right") +
  labs(title="Grouped barplot",subtitle="With values printed above") +
  geom_text(aes(group=Group),position=position_dodge(width=0.9),size=3,vjust=-0.5,hjust=0.5) #This is for the labels

Stacked barplot

set.seed(1)
dat <- data.frame(Group=factor(c('Youngest','Young',"Older","Oldest"),levels=c('Youngest','Young',"Older","Oldest")),
                  Sex=sample(c("Male","Female"),100,rep=T))


dat.melt <- melt(dat, id.vars='Group')


ggplot(dat.melt) +
  geom_bar(aes(x=Group,fill = value), position = "stack",width=0.6) +
  theme(legend.position = "right") +
  labs(title="Gender distribution within age subsets",subtitle="Dummy data to show use of stacked bars")

Vertical barplot

cardata <- mtcars
cardata$Model <- rownames(cardata)

ggplot(cardata,aes(x=reorder(Model,mpg),y=mpg)) +
  geom_bar(width = 0.7,stat="identity",fill="tomato") +
  theme(legend.position = "none") + coord_flip() +
  labs(title="Miles pr. galon for various car models",subtitle="Vertical barplot example",x="")

Histograms with several groups

set.seed(1)
a <- rnorm(n = 10000,mean = -1,sd = 0.7)
b <- rnorm(n = 10000,mean=-2,sd=1.25)
c <- rnorm(n=10000,mean=-1,sd=2)
d <- rnorm(n=10000,mean=2,sd=0.5)

groupvec <- c(rep("a",10000),rep("b",10000),rep("c",10000),rep("d",10000))

datavec <- c(a,b,c,d)

histframe <- data.frame(groupvariable=groupvec,datavec)

ggplot(histframe,aes(x=datavec,fill=groupvariable)) +
#Must use identity when plotting multiple histograms, else the result is one weird combined histogram
geom_histogram(position = "identity",alpha=0.6,binwidth = 0.05) + 
labs(title="Overlay histograms",subtitle="Properly plot more than one histogram on same chart")

Faceting

set.seed(1)
options(scipen=999)
#Make dataset with 12 groups with different distributions
mat <- matrix(nrow=10000,ncol=2)

mat[,1] <- rnorm(10000,1,2)
mat[,2] <- sample(letters[1:12],10000,rep=T)

mat <- data.frame(dat=as.numeric(mat[,1]),group=mat[,2])

ggplot(mat,aes(x=dat,fill=group)) + geom_histogram(alpha=0.5,binwidth = 0.1) + facet_wrap(~group) + theme(legend.position = "none") + theme(strip.background = element_rect(fill = "white",colour="gray")) + labs(title="Faceting plots on a factor",x="Xval")

Density for several groups overlay

set.seed(1)
a <- rnorm(n = 10000,mean = 0,sd = 1)
b <- rnorm(n = 10000,mean=1.25,sd=1.25)
c <- rnorm(n=10000,mean=-0.8,sd=2)

groupvec <- c(rep("a",10000),rep("b",10000),rep("c",10000))

datavec <- c(a,b,c)

histframe <- data.frame(groupvariable=groupvec,datavec)



ggplot(histframe,aes(x=datavec,fill=groupvariable)) +
geom_density(alpha=0.5) +
scale_fill_brewer(type="qual",palette = 6) +
labs(title="Overlaid densities",subtitle="Three densities with different properties. Specific palette.",x="",fill="Group") +
theme(plot.margin = unit(c(1.0,0,0,0),"cm")) + #Kun for at plot ikke skal kommen for nær kode
theme(panel.border = element_blank(),
      legend.position = c(0.9,0.57))




Adding descriptive tables to a plot

set.seed(25)
Group <- sample(c("a","b","c","d","e"),size=50,rep=T)
Value <- rnorm(50,mean=1,sd=20)

df <- data.frame(Group,Value)

#Calculate maximum value within each group
library(data.table)
df <- data.table(df)
dfSum <- df[,.(MaxVal=max(Value)),by=Group]

setorder(dfSum,Group)
dfSum$MaxVal <- round(dfSum$MaxVal,2)

library(gridExtra)

#Define some visual elements for the table
mytheme <- gridExtra::ttheme_minimal(core = list(fg_params=list(cex = 0.8)),
colhead = list(fg_params=list(cex = 0.7)),
rowhead = list(fg_params=list(cex = .5)),padding = unit(c(2, 2), "mm"))



ggplot(dfSum,aes(x=Group,fill=Group,y=MaxVal)) +
  geom_bar(width = 0.6,stat="identity") +
  theme(legend.position = "none") +
  labs(title="Adding a table to a plot") +
annotation_custom(tableGrob(dfSum,rows = NULL,theme = mytheme), xmin=4, xmax=6, ymin=30, ymax=40) #this is the table

Boxplot

ggplot(mtcars,aes(x=factor(gear),y=mpg,fill=factor(gear))) +
  geom_boxplot(width =0.3) +
  theme(legend.position = "none") +
  labs(title="Boxplot: Mpg vs. number of gears",x="Number of gears")

Boxplots with multiple group comparisons

Compare distributions within two groups for a range of a categorical value

#Generate dataframe with simulated wagedata:
#Males have higher salaries than females
#Wage is divided into levels 1-4
set.seed(1)

WagelevelFac <- c(1,1.1,1.2,1.4)
Femalewages <- rnorm(1000,10000,1000)
Malewages <- rnorm(1000,11000,1000)

#Multiply all the wages for males and females by the weight vector to make all the subgroups
Wagevec <- c(WagelevelFac%*%t(Femalewages),WagelevelFac%*%t(Malewages))

#The next two lines is examples of how to manually sort factors in order to make them appear on the plot in the desired order
Sex <- factor(c(rep("Female",4000),rep("Male",4000)),levels=c("Male","Female"))
WagelevelFactor <- rep(factor(c("Low","Normal","High","Very High"),levels=c(c("Low","Normal","High","Very High"))),2000)


df <- data.frame(Sex,WageLevel=WagelevelFactor,Wage=Wagevec)

ggplot(aes(y = Wage, x = WageLevel, fill = Sex), data = df) +
  geom_boxplot(position = position_dodge(width = 0.6),width=0.3,outlier.colour = NA) +
  theme(legend.position = c(1.03,0.97),legend.title = element_blank(),plot.margin = unit(c(1,2,0.2,0.2),"cm")) +
  scale_fill_brewer(type="qual",palette=5) +
  labs(title="Wage vs gender by wage segment",subtitle="Dummy data to show multi-category comparisons",x="Wage level",y="Yearly salary")

Arrange multiple plots on a grid

Put plots side by side or in some other configuration

In this example:

Plot1: Compare distribution of some variable between two populations.
Plot2: Show the effect the variable in Plot 1 has on some outcome.

set.seed(2)

#create two populations with different distributions for age
Oldergroup <- as.integer(rbeta(10000,5,3)*80)
Youngergroup <- as.integer(rbeta(10000,3,8)*80)
groupvar <- c(rep("Younggroup",10000),rep("Oldgroup",10000))
Agedf <- data.frame(Age=c(Youngergroup,Oldergroup),Group=groupvar)

#Create first plot. Overlaid densities
AG <- ggplot(Agedf,aes(x=Age,fill=Group)) +
geom_density(alpha=0.7) +
scale_fill_brewer(type="qual",palette = 6) +
theme(plot.margin=unit(c(1,0.2,0.9,0.2), "cm"),legend.position = c(0.84,0.9),legend.title = element_blank()) +
labs(subtitle="Group age density. Years",x="",y="")


#Create dummydata for probability of getting stroke
Agedf$strokeProb <- 0.05+Agedf$Age*0.005+(Agedf$Age**2*0.00005)+rnorm(20000,sd=1,mean = 0)-0.1
Agedf$strokeProb[Agedf$strokeProb>1] <- rnorm(length(Agedf$strokeProb[Agedf$strokeProb>1]),mean = 0.75)
Agedf$strokeProb[Agedf$strokeProb<0] <- 0
Agedf$Stroke <- ifelse(runif(20000)<Agedf$strokeProb,1,0)

#summarize Stroke pr. agegroup
library(data.table)
AgeSum <- data.table(Age=Agedf$Age,Stroke=Agedf$Stroke)
AgeSum$AgeGroup <- cut(AgeSum$Age,breaks = seq(0,81,by=10),include.lowest = T)
AgeSum <- AgeSum[,.(StrokeFraction=mean(Stroke)*100,N=.N),by=AgeGroup]

#Create plot of age vs. strokefrac
SF <- ggplot(AgeSum,aes(x=AgeGroup,y=StrokeFraction)) +
geom_bar(stat="identity",fill="red",alpha=0.7,color="black") +
theme(axis.text.x = element_text(angle = 45, hjust = 1) ,plot.margin=unit(c(1,0.2,0.2,0), "cm")) +
labs(subtitle="Agegroup probability of stroke. Percent.",x="",y="") +
theme(panel.border = element_blank())



#Juxtapose and plot
#multiplot(AG,SF,cols = 2)
library(gridExtra)
library(grid)
grid.arrange(AG,SF,ncol=2,top=textGrob("Arranging plots on a grid",gp=gpar(fontface="bold"))) #Adding a main title

Geo plotting (Maps)

library(ggmap)

myMap <- get_googlemap(center=c(lat=6,lon=58.8),zoom=8,maptype = "hybrid",message = FALSE,verbose=F)

myMaprender <- ggmap(myMap)

#Make dataframe of city populations
popSizeFrame <- data.frame(By=c("Sola","Tau","Jørpeland","Bryne","Haugesund"),lat=c(58.8888,59.0648,59.0221,58.7358,59.4136),lon=c(5.6530,5.9225,6.0415,5.6477,5.2680),pop=c(26000,3000,6948,11569,36538))

myMaprender + geom_point(data=popSizeFrame,aes(x=lon,y=lat,size=pop),alpha=0.9,color="tomato") +
labs(size="Population") + #Trick to change the legend title
theme(legend.position=c(0.07,0.9)) +
theme(axis.line=element_blank(), #Remove margins axis lines etc.
axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks=element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank(),
#panel.background=element_blank(),
panel.border = element_rect(colour = "grey", fill=NA, size=1),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
#plot.background=element_blank(),
legend.key = element_blank()) +
scale_size_area(max_size=7,breaks=c(3000,5000,10000,20000,30000,40000)) +
labs(title="Plotting on google maps")

Heatmap on map (2d density)

library(ggmap)
options(scipen = 999)

loc <- c()

myMap <- get_googlemap(center=c(lat=5.7331,lon=58.9700),zoom=14,maptype = "roadmap")
myMaprender <- ggmap(myMap) #This is the background map (a ggplot object)

#Generate data for the 2d density
set.seed(2)
center1 <- matrix(c(rnorm(1500,58.975,0.004),rnorm(1500,5.72,0.004)),ncol = 2)
center2 <- matrix(c(rnorm(700,58.97,0.005),rnorm(700,5.732,0.002)),ncol = 2)
center3 <- matrix(c(rnorm(300,58.967,0.002),rnorm(300,5.718,0.004)),ncol = 2)

dummydat <- data.frame(rbind(center1,center2,center3))
colnames(dummydat) <- c("lon","lat")


MapW2dDensity <- myMaprender + stat_density2d(data=dummydat,aes(x=lat,y=lon,alpha=..level..),fill="red",geom="polygon") + scale_alpha_continuous(range=c(0,0.25)) +

labs(size="Population") + #Trick to change the legend title
theme(legend.position="none") +
theme(axis.line=element_blank(), #Remove margins axis lines etc.
axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks=element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank(),
panel.background=element_blank(),
panel.border = element_rect(colour = "grey", fill=NA, size=1),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
plot.background=element_blank(),
legend.key = element_blank(),
plot.title = element_text(vjust=1),
plot.margin=unit(c(0.7,0.1,0.1,0.1),"cm")) +
labs(title="Awesomeness concentration levels in central Stavanger",x="",y="")

MapW2dDensity

Inset on plot

This example shows how to insert one plot of any kind into another. Continue with last example. Make a small inset plot to better highlight the geom.

library(grid)
library(gridExtra)

#Create overlay plot object
overlay <- stat_density2d(data=dummydat,aes(x=lat,y=lon,alpha=..level..),fill="red",geom="polygon")

#The next lines of code is made so that the inset can be placed on the original plot using x and y values ranging from 0-1
#This eases the placement of the inset considerably

#Extract ranges of original object to determine placement on 0-1 scale
xrange <- ggplot_build(MapW2dDensity)$layout$panel_ranges[[1]]$x.range
yrange <- ggplot_build(MapW2dDensity)$layout$panel_ranges[[1]]$y.range

placement <- c(0.75,0.05) #x,y Lower left corner placement
size <- 0.2            #Size (in this example a square)

xvalsNorm <- c(placement[1],placement[1]+size) #vector with xmin and xmax values, normalized
xvalsDenorm <- (xvalsNorm*(xrange[2]-xrange[1]))+xrange[1] #xvals projected back to original axis levels

yvalsNorm <- c(placement[2],placement[2]+size) #vector with ymin and ymay values, normalized
yvalsDenorm <- (yvalsNorm*(yrange[2]-yrange[1]))+yrange[1] #yvals projected back to original ayis levels


#Plot the map and the inset
MapW2dDensity   + labs(subtitle="Add small inset plot to better show the 2d density shapes") +
inset(grob = ggplotGrob(ggplot() + overlay +
                          scale_alpha_continuous(range=c(0,0.6)) +
                          theme_inset()+
                          theme(panel.border = element_rect(colour = "gray7", fill=NA, size=0.2),
                          panel.grid.major = element_line(size=0.2,colour = "mistyrose"))
                        +xlim(xrange)+ylim(yrange)), #This line code is very important to keep relative consistent coords of inset to original plot. Else the inset will use its own axis ranges
      xmin = xvalsDenorm[1], xmax = xvalsDenorm[2], ymin = yvalsDenorm[1], ymax = yvalsDenorm[2]) #Position of inset

Heatmap with 3rd variable as weight

Similar to the last plots but with a third variable as the weight (instead of just equally weighted occurence as previous examples)

# Generate data
library(reshape2) # for melt
volcano3d <- melt(volcano)
names(volcano3d) <- c("x", "y", "Temp")

# Basic plot
v <- ggplot(volcano3d, aes(x, y, z = Temp))
v + geom_tile(aes(fill = Temp)) + stat_contour(colour="grey") + scale_fill_gradient(low="white",high="red") + labs(title="Volcano temperatures")

Use custom palettes

Examples using the colorspace library as a way to control the palettes used.

Alternative 1: use predefined palette.

library(colorspace) #Palette library

set.seed(2)
Group <- sample(c("a","b","c","d","e"),prob = c(0.2,0.2,0.15,0.3,0.15),size = 1000,rep=T)
Value <- rnorm

df <- data.frame(Group)
ggplot(df,aes(x=Group,fill=Group)) + geom_bar(width = 0.6) + theme(legend.position = "none") +
  #Use specified palette for fill
  scale_fill_brewer(palette="Pastel1",type="qual")


Alternative 2: Make custom palette.

library(colorspace) #Palette library
#Create custom palette, c & l vars indicate lumosity and chromatism. Use custpal <- choose_palette() create via gui.
custpal <- rainbow_hcl(5,start=0,end=150,l = 50,c=80)

set.seed(2)
Group <- sample(c("a","b","c","d","e"),prob = c(0.2,0.2,0.15,0.3,0.15),size = 1000,rep=T)
Value <- rnorm

df <- data.frame(Group)
ggplot(df,aes(x=Group,fill=Group)) + geom_bar(width = 0.6) +
 theme(legend.position = "none") +
  scale_fill_manual(values=custpal)

Extra: Color library & table output

Color library of some colors i have used. In addition this example shows how to use formattable for markdowns.

#HexColTmp <- c("red", "blue","salmon","pink","aliceblue","brown","yellow","lightgreen","purple")

HexColTmp <- c("#FB6542", "#3F681C","#DE7A22","#6AB187","#C05805","#b6452c","#2988BC","#662e1c","#e1315b")
HexCol <- factor(HexColTmp,levels = HexColTmp)

yy <- rep(1,length(HexCol))
colNo <- 1:length(HexCol)

df <- data.frame(HexCol,yy,colNo)



ggplot(data=df,aes(x=HexCol,y=yy,fill=HexCol,labels=colNo)) +
  geom_bar(stat="identity",width = 0.8) +
  scale_fill_manual(values = HexColTmp) +
  geom_text(aes(label=colNo),vjust=11,size=5) +
  theme(legend.position = "none",axis.line = element_blank(),axis.title = element_blank(),axis.text.y = element_blank(),axis.ticks.y = element_blank())

#Output with nice table
library(formattable)
t <- as.htmlwidget(formattable(df[,c(3,1)],row.names=F,align="l"),width="50%")
t