Search code examples
rplotlabelpanel

How to add tick marks on a plot that is not from plot() in R


I use a R package, SetMethods, to get the fsQCA results of panel data. In the package, it uses cluster.plot() function to generate a plot.

However, I have a hard time letting the x-axis of the graph show the number of units as tick marks. For example, I want it shows 10, 20, 30,..,140 on the x-axis to know how many units' consistency score lower than a certain point.

Is there any method to add tick marks on a plot that is not generated by plot() function? Thanks in advance.

Here I use the dataset in the package as an example.

install.packages("SetMethods")
library(SetMethods)

data("PAYF")
PS <- minimize(data = PAYF,
               outcome  = "HL",
               conditions = c("HE","GG","AH","HI","HW"),
               incl.cut = 0.9,
               n.cut = 2,
               include = "?",
               details = TRUE, 
               show.cases = TRUE)
PS

# Perform cluster diagnostics:

CB <- cluster(data = PAYF,
              results = PS,
              outcome = "HL",
              unit_id = "COUNTRY",
              cluster_id = "REGION",
              necessity=FALSE,
              wicons = FALSE)
CB

# Plot pooled, between, and within consistencies:

cluster.plot(cluster.res = CB,
             labs = TRUE,
             size = 8,
             angle = 6,
             wicons = TRUE)

Finally, I get a graph as follows.

enter image description here

However, I want it shows 10, 20, 30,..,140 on the x-axis to know how many units' consistency score lower than a certain point.

Is there any method to add tick marks on a plot that is not generated by plot() function? Thanks in advance.


Solution

  • If you look inside the cluster.plot function definition (in RStudio press F2 while pointer is on it) you will see that it uses ggplot2 under the hood. Only it doesn't return ggplot2 objects but just prints them one over another. Because of this it's not really possible to modify the output afterwards in any covenient manner.

    But you can always copy the function code and rewrite it for your own need. The part that prints the final plot in your case is

    CTw <- list()
    ticklabw = unique(as.character(cluster.res$unit_ids))
    xtickw <- seq(1, length(ticklabw), by = 1)
    if (class(cluster.res) == "clusterminimize") {
      for (i in 1:length(cluster.res$output)) {
        CTw[[i]] <- cluster.res$output[[i]]$WICONS
        dtw <- data.frame(x = xtickw, y = CTw[[i]])
        dtw <- dtw[order(dtw$y), ]
        dtw$xr <- reorder(dtw$x, 1 - dtw$y)
        pw <- ggplot(dtw, aes(y = dtw[, 2], x = dtw[, 
          3])) + geom_point() + ylim(0, 1) + theme_classic(base_size = 16) + 
          geom_hline(yintercept = cluster.res$output[[i]]$POCOS) + 
          labs(title = names(cluster.res$output[i]), 
            x = "Units", y = "Consistency") + theme(axis.text.x = element_blank())
        suppressWarnings(print(pw))
      }
    }
    

    You can modify the ggplot2 construction part to something like this (packages ggplot2 and dplyr need to be loaded):

    pw <- 
      dtw %>% 
      mutate(x_ind = as.numeric(xr)) %>% 
      ggplot(aes(x_ind, y)) +
      geom_point() +
      ylim(0, 1) +
      theme_classic(base_size = 16) + 
      geom_hline(yintercept = cluster.res$output[[i]]$POCOS) + 
      scale_x_continuous(breaks = seq(from = 0, to = 140, by = 10)) +
      labs(title = names(cluster.res$output[i]),
        x = "Units", y = "Consistency")
    

    enter image description here