Replace x-axis label from the plot of a MarkovChain object

73 Views Asked by At

Here is some code to generate a 0th order Markov Chain plot. I'd like to replace the plot's x-axis labels (c, d, h, i, o, p) with 45 degree rotated labels showing the first six months of the year. However, using xaxt="n" in the plot call doesn't seem to work. This code just writes over the existing labels, rather than replacing them. How can I replace the labels with the ones I want?

library(clickstream)
clickstreams <- c("User1,h,c,c,p,c,h,c,p,p,c,p,p,o",
                   "User2,i,c,i,c,c,c,d",
                   "User3,h,i,c,i,c,p,c,c,p,c,c,i,d",
                   "User4,c,c,p,c,d",
                   "User5,h,c,c,p,p,c,p,p,p,i,p,o",
                   "User6,i,h,c,c,p,p,c,p,c,d")
csf <- tempfile()
writeLines(clickstreams, csf)
cls <- readClickstreams(csf, header = TRUE)
mc <- fitMarkovChain(cls, order=0)
plot(mc, xaxt="n")
text(x=1:6, y=par()$usr[3], labels = month.name[1:6], srt=45, adj = c(1.1,1.1), xpd = TRUE, cex=.9)

clickstream plot with wrong x-axis labels

2

There are 2 best solutions below

0
On BEST ANSWER

str(mc) reveals the structure of the S4 object. Passing into plot just the xy-coordinates rather than the whole "MarkovChain" object recovers the xaxt option functionality. Using with makes this most convenient.

Moreover this allows us to use the implemented S4 plot method for signature 'MarkovChain' of the clickstream package.

library(clickstream)
with(mc@transitions[[1]], plot(states, probability, xaxt="n"))
text(x=1:6, y=par()$usr[3], labels=month.name[1:6], srt=45, adj=rep(1.1, 2), xpd=TRUE, cex=.9)

Result

enter image description here

Data

library(clickstream)
mc <- new("MarkovChain", states = c("h", "c", "p", "o", "i", "d"), 
    order = 0, transitions = list(structure(list(states = structure(1:6, .Label = c("c", 
    "d", "h", "i", "o", "p"), class = "factor"), frequency = c(25L, 
    4L, 5L, 7L, 2L, 17L), probability = c(0.416666666666667, 
    0.0666666666666667, 0.0833333333333333, 0.116666666666667, 
    0.0333333333333333, 0.283333333333333)), class = "data.frame", row.names = c(NA, 
    -6L))), lambda = 0, logLikelihood = -88.4241188515082, observations = 60, 
    start = structure(c(c = 0.166666666666667, h = 0.5, i = 0.333333333333333
    ), class = "table", .Dim = 3L, .Dimnames = structure(list(
        c("c", "h", "i")), .Names = "")), end = structure(c(d = 0.666666666666667, 
    o = 0.333333333333333), class = "table", .Dim = 2L, .Dimnames = structure(list(
        c("d", "o")), .Names = "")), transientStates = c("c", 
    "h", "i", "p"), absorbingStates = c("d", "o"), absorbingProbabilities = structure(list(
        state = structure(1:4, .Label = c("c", "h", "i", "p"), class = "factor"), 
        d = c(0.792201957232916, 0.864224245314581, 0.903842865008182, 
        0.517925028202586), o = c(0.207798042767084, 0.13577575468542, 
        0.0961571349918185, 0.482074971797414)), class = "data.frame", row.names = c(c = 1L, 
    h = 3L, i = 4L, p = 6L)))
3
On

Using plot.default rather than plot exposes the graphics plot function, which allows the use of the xaxt function parameter to remove the existing x-axis labels. Since plot.default won't accept a MarkovChain object, the x and y values for the plot need to be extracted from the object.

plot.default(
   x=mc@transitions[[1]]$states, 
   y=mc@transitions[[1]]$probability,
   xaxt="n", 
   ann=FALSE, 
   pch="-", 
   cex=3
)

text(
    x = 1:6, 
    y = par()$usr[3], 
    labels = month.name[1:6], 
    srt = 45, 
    adj = c(1.1,1.1), 
    xpd = TRUE, 
    cex = .9
)

enter image description here