Reputation: 107
I am trying to present the following data
x <- factor(c(1,2,3,4,5))
x
[1] 1 2 3 4 5
Levels: 1 2 3 4 5
value <- c(10,5,7,4,12)
value
[1] 10 5 7 4 12
y <- data.frame(x, value)
y
x value
1 1 10
2 2 5
3 3 7
4 4 4
5 5 12
I want to convert the above information into the following graphical representation
What is the above type of graphs called. I checked out dot plot, but that only stacks vertically.
Upvotes: 3
Views: 221
Reputation: 1015
This solution plots sets of three bar graphs facetted by x
. The height of the bars within each set is determined using the remainder from dividing value
by 3. Horizontal spacing is provided by natural geom spacing. Vertical spacing is created using white gridlines.
library(ggplot2)
library(reshape2)
dataset <- data.frame('x' = 1:5, 'value' = c(10, 5, 7, 4, 12))
Since every value
is supposed to be represented by three bars, we will add 3 columns to the dataset and distribute the magnitude of the value
among them using integer division:
dataset[, c('col1', 'col2', 'col3')] <- floor(dataset$value / 3)
r <- dataset$value %% 3
dataset[r == 1, 'col1'] <- dataset[dataset$value %% 3 == 1, 'col1'] + 1
dataset[r == 2, c('col1', 'col2')] <- dataset[r == 2, c('col1', 'col2')] + 1
Now, we will melt the dataframe for the purposes of plotting:
dataset <- melt(dataset, id.vars = c('x', 'value'))
colnames(dataset)[4] <- 'magnitude' # avoiding colnames conflict
dataset$variable <- as.character(dataset$variable) # column ordering within a facet
First, we will make a regular bar graph. We can move facet labels to the bottom of the plot area using the switch
parameter.
plt <- ggplot(data = dataset)
plt <- plt + geom_col(aes(x=variable, y = magnitude), fill = 'black')
plt <- plt + facet_grid(.~x, switch="both")
Then we will use theme_minimal()
and add a few tweaks to the parameters that govern the appearance of gridlines. Specifically, we will make sure that minor XY gridlines and major X gridlines are blank, whereas major Y gridlines are white and plotted on top of the data.
plt <- plt + theme_minimal()
plt <- plt + theme(panel.grid.major.x = element_blank(),
panel.grid.major.y = element_line(colour = "white", size = 1.5),
panel.grid.minor = element_blank(),
panel.ontop = TRUE)
We can add value
labels using geom_text()
. We will only use x
values from col2
records such that we're not plotting the value over each bar within each set (col2
happens to be the middle bar).
plt <- plt + geom_text(data = dataset[dataset$variable == 'col2', ],
aes(label = value, x = variable, y = magnitude + 0.5))
plt <- plt + theme(axis.text.x=element_blank()) # removing the 'col' labels
plt + xlab('x') + ylab('value')
Upvotes: 7
Reputation: 76470
The following code will do a graph similar to the one in the question.
I had to change the data.frame, yours was not fit to graph with geom_dotplot
. The new variable z$value
is a vector of the values 1:5
each repeated as many times as value
.
library(ggplot2)
value <- c(10, 5, 7, 4, 12)
z <- sapply(value, function(v) c(1, rep(0, v - 1)))
z <- cumsum(unlist(z))
z <- data.frame(value = z)
ggplot(z, aes(x = jitter(value))) +
geom_dotplot() +
xlab("value")
Upvotes: 1