1

I have created the a chart in ggplot2 using the data shown here:

  Categories       A1       A2       A3       A4       A5
1       XX_1   41.151   61.017   67.639     94.6  137.643
2       XX_2  93.4175 127.4735    141.9  153.252  180.213
3       YY_1 160.5835  169.807  166.969 169.5705   184.47
4       YY_2  171.226 184.7065 194.1665 187.0715  218.526
5       ZZ_1  83.4845   97.438   122.98 127.4735 140.7175
6       ZZ_2 126.5275  139.535  140.954  157.982  183.524
8       LL_1   81.829   72.842  67.8755    56.76   48.246
9       LL_2   58.652   52.976  41.8605   32.164  31.9275

As you can see in the data that there are three sets of similar categories—XX, YY, ZZ, LL. These categories also have two sub-division-- _1 and _2. When I plot the data, all the categories are plotted equidistant from each other as shown in the chart here

enter image description here

However, I want the similar categories like LL_1 and LL_2 to be closer to each other, and the space between different pairs like XX , ZZ, YY, and YY to increase. I don't want all the categories to be equidistant from each other. I want to custom change the distance of similar and dissimilar categories. As shown in a rough Chart1 here:

enter image description here

I also don't want to use facet_wrap, and would like all the data to be shown in the same chart. I would really appreciate if someone could guide on how to solve this problem.

Below is the code i used to plot the chart:

##Loading the excel data
df <- read_excel("~\Sample.xlsx")

##Converting from wide to long format
df1 <- melt(df, id.vars = "Categories", measure.vars = c("A1", "A2", "A3", "A4", "A5"), variable.name = "AA", value.name = "values")

df1 <- df1[order(df1$Categories), ]

##Plotting the data
p6 <- ggplot(data = df1, mapping = aes(x=values, y=Categories))
p6 + geom_line(color="brown", size=0.1)+ geom_point(aes(color=AA), size=0.5)+
  theme(axis.title.y = element_blank(), axis.text = element_text(face = "bold"),axis.text.y = element_text(size = 2.2),
        axis.text.x = element_text(size = 2.2), axis.title.x = element_text(size = 2.5), axis.line.x = element_line(size = 0.2), axis.line.y = element_line(size = 0.2),
        axis.ticks = element_line(size = 0.2),axis.ticks.length = unit(0.03, "cm"),
        legend.key = element_blank(), legend.spacing.y = unit(0.05, "cm"), legend.key.size = unit(0.2, "cm"),
        legend.title = element_text(face = "bold", size = 2.5),legend.text = element_text(size = 2), panel.background = element_blank(), panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"), panel.border = element_blank())+ 
  scale_x_continuous(breaks=seq(0,220,5))+
  labs(x="Number", color="Category")


Thanks

sid
  • 15
  • 4
  • Welcome to StackOverflow. Please take some effort to improve your question by providing a working example. This will helps others to help you. Take a look at https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – Janhoo Mar 05 '20 at 12:58
  • Why don't you want to use facets? `facet_grid` would allow you to space your groups independently. You can then format the facets so they look just like in your second picture, and this would be a more authentic presentation of the data than hacking in empty spaces on the axis that don't actually correspond to data. Saying all this because I do charts just like this pretty often – camille Mar 05 '20 at 14:30
  • Also, seeing the code that makes this chart would be helpful, especially since the snippet of data you've shown doesn't lend itself to using ggplot without reshaping it – camille Mar 05 '20 at 14:31
  • Hi Camille, Edited the post to add the code. Thanks – sid Mar 05 '20 at 17:46

2 Answers2

5

To get a custom categorical y-axis you could use continuous values for y-axis values and then set custom breaks and labels for the y-axis. Example here:

library(ggplot2)

df <- data.frame(
  cat = c("AA_1", "AA_2", "BB_1", "BB_2", "CC_1", "CC_2"),
  catval = c(1,2,4,5,7,8),
  value = rnorm(6)
)

ggplot(df, aes(value, catval)) +
  geom_point() +
  scale_y_continuous(breaks = df$catval, 
                     labels = df$cat)

enter image description here

teunbrand
  • 33,645
  • 4
  • 37
  • 63
1

I have recreated the data you posted in image format and added it to your question. This allowed me to reproduce your plot by reordering the factor levels with blanks in between:

df$Group <- factor(df$Group, levels = c("XX_1", "XX_2", " ", "YY_1", "YY_2", 
                                        "  ", "ZZ_1", "ZZ_2", "   ", "LL_1", "LL_2"))

df$Group_numbers <- as.numeric(df$Group)
ggplot(df, aes(x = Number, y = Group_numbers)) + 
  geom_line(aes(group = Group_numbers)) + 
  geom_point(aes(colour = Category), size = 3) + 
  scale_y_continuous(breaks = 1:11, labels = levels(df$Group)) +
  labs(y = "") + theme_bw() +
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())

enter image description here


Data used - taken from sample image and pivoted to allow easier plotting

df <- structure(list(Group = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 
5L, 5L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 
8L), .Label = c("XX_1", "XX_2", "YY_1", "YY_2", "ZZ_1", "ZZ_2", 
"LL_1", "LL_2"), class = "factor"), Category = c("A1", "A2", 
"A3", "A4", "A5", "A1", "A2", "A3", "A4", "A5", "A1", "A2", "A3", 
"A4", "A5", "A1", "A2", "A3", "A4", "A5", "A1", "A2", "A3", "A4", 
"A5", "A1", "A2", "A3", "A4", "A5", "A1", "A2", "A3", "A4", "A5", 
"A1", "A2", "A3", "A4", "A5"), Number = c(41.151, 61.017, 67.639, 
94.6, 137.643, 93.4175, 127.4735, 141.9, 153.252, 180.213, 160.5835, 
169.807, 166.969, 169.5705, 184.47, 171.226, 184.7065, 194.1665, 
187.0715, 218.526, 83.4845, 97.438, 122.98, 127.4735, 140.7175, 
126.5275, 139.535, 140.954, 157.982, 183.524, 81.829, 72.842, 
67.8755, 56.76, 48.246, 58.652, 52.976, 41.8605, 32.164, 31.9275
)), row.names = c(NA, -40L), class = "data.frame")
Allan Cameron
  • 147,086
  • 7
  • 49
  • 87