Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8397569
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T20:49:31+00:00 2026-06-09T20:49:31+00:00

I have a classification tree analyzed using ctree() was wondering how can one rotate

  • 0

I have a classification tree analyzed using ctree() was wondering how can one rotate the terminal nodes so that the axes are vertical?

library(party)
data(iris)
attach(iris)
plot(ctree(Species ~ Sepal.Length + Sepel.Width 
     + Petal.Length + Petal.Width, data = iris))
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T20:49:33+00:00Added an answer on June 9, 2026 at 8:49 pm

    Here is how I would go about it. Not the shortest answer, but I wanted to be as thorough as possible.

    Since we are plotting your tree, it’s probably a good idea to look at the documentation for the appropriate plotting function:

    library(party)
    data(iris)
    attach(iris)
    
    ctree <- ctree(Species ~ Sepal.Length + Sepal.Width 
                   + Petal.Length + Petal.Width, data = iris)
    
    # getting ctree's class
    
    > class(ctree)
    [1] "BinaryTree"
    attr(,"package")
    [1] "party"
    

    Looking at ?'plot.BinaryTree' we see the following description of the terminal_panel argument:

    an optional panel function of the form function(node)
    plotting the terminal nodes. Alternatively, a panel generating
    function of class “grapcon_generator” that is called with arguments x
    and tp_args to set up a panel function. By default, an appropriate
    panel function is chosen depending on the scale of the dependent
    variable.

    Further down in the documentation is a link to ?node_barplot. This is what I guessed was being used as a default, and calling the following proved the guess right:

    plot(ctree, terminal_panel = node_barplot(ctree))
    

    (The output is the same as your original graph).

    Unfortunately, there’s no horizontal or horiz parameters for node_barplot. Looking at the code for this function, by simply typing node_barplot at the prompt, reveals that the graphs are drawn “by hand” using viewports. Unfortunately, the only way I could find to proceed was to edit this function. I tried to make my changes as obvious as possible:

    # Note inclusion of horiz = FALSE
    alt_node_barplot <- function (ctreeobj, col = "black", fill = NULL, beside = NULL, 
        ymax = NULL, ylines = NULL, widths = 1, gap = NULL, reverse = NULL, 
        id = TRUE, horiz = FALSE)
    {
        getMaxPred <- function(x) {
            mp <- max(x$prediction)
            mpl <- ifelse(x$terminal, 0, getMaxPred(x$left))
            mpr <- ifelse(x$terminal, 0, getMaxPred(x$right))
            return(max(c(mp, mpl, mpr)))
        }
        y <- response(ctreeobj)[[1]]
        if (is.factor(y) || class(y) == "was_ordered") {
            ylevels <- levels(y)
            if (is.null(beside)) 
                beside <- if (length(ylevels) < 3) 
                    FALSE
                else TRUE
            if (is.null(ymax)) 
                ymax <- if (beside) 
                    1.1
                else 1
            if (is.null(gap)) 
                gap <- if (beside) 
                    0.1
                else 0
        }
        else {
            if (is.null(beside)) 
                beside <- FALSE
            if (is.null(ymax)) 
                ymax <- getMaxPred(ctreeobj@tree) * 1.1
            ylevels <- seq(along = ctreeobj@tree$prediction)
            if (length(ylevels) < 2) 
                ylevels <- ""
            if (is.null(gap)) 
                gap <- 1
        }
        if (is.null(reverse)) 
            reverse <- !beside
        if (is.null(fill)) 
            fill <- gray.colors(length(ylevels))
        if (is.null(ylines)) 
            ylines <- if (beside) 
                c(3, 2)
            else c(1.5, 2.5)
        # My edit do not work if beside is not true
        #################################################
        if(!beside) horiz = FALSE
        #################################################
    
        rval <- function(node) {
            pred <- node$prediction
            if (reverse) {
                pred <- rev(pred)
                ylevels <- rev(ylevels)
            }
            np <- length(pred)
            nc <- if (beside) 
                np
            else 1
            fill <- rep(fill, length.out = np)
            widths <- rep(widths, length.out = nc)
            col <- rep(col, length.out = nc)
            ylines <- rep(ylines, length.out = 2)
            gap <- gap * sum(widths)
            #######################################################
            if (!horiz){
                yscale <- c(0, ymax)
                xscale <- c(0, sum(widths) + (nc + 1) * gap)
            } else {
                xscale <- c(0, ymax)
                yscale <- c(0, sum(widths) + (nc + 1) * gap)
            }                    
            #######################################################
            top_vp <- viewport(layout = grid.layout(nrow = 2, ncol = 3, 
                widths = unit(c(ylines[1], 1, ylines[2]), c("lines", 
                    "null", "lines")), heights = unit(c(1, 1), c("lines", 
                    "null"))), width = unit(1, "npc"), height = unit(1, 
                "npc") - unit(2, "lines"), name = paste("node_barplot", 
                node$nodeID, sep = ""))
            pushViewport(top_vp)
            grid.rect(gp = gpar(fill = "white", col = 0))
            top <- viewport(layout.pos.col = 2, layout.pos.row = 1)
            pushViewport(top)
            mainlab <- paste(ifelse(id, paste("Node", node$nodeID, 
                "(n = "), "n = "), sum(node$weights), ifelse(id, 
                ")", ""), sep = "")
            grid.text(mainlab)
            popViewport()
            plot <- viewport(layout.pos.col = 2, layout.pos.row = 2, 
                xscale = xscale, yscale = yscale, name = paste("node_barplot", 
                    node$nodeID, "plot", sep = ""))
            pushViewport(plot)
            if (beside) {
                #############################################################
                if(!horiz){
                    xcenter <- cumsum(widths + gap) - widths/2
                    for (i in 1:np) {
                        grid.rect(x = xcenter[i], y = 0, height = pred[i], 
                          width = widths[i], just = c("center", "bottom"), 
                          default.units = "native", gp = gpar(col = col[i], 
                            fill = fill[i]))
                    }
                    if (length(xcenter) > 1) 
                        grid.xaxis(at = xcenter, label = FALSE)
                    grid.text(ylevels, x = xcenter, y = unit(-1, "lines"), 
                        just = c("center", "top"), default.units = "native", 
                        check.overlap = TRUE)
                    grid.yaxis()
                } else {
                    ycenter <- cumsum(widths + gap) - widths/2
                    for (i in 1:np) {
                        grid.rect(y = ycenter[i], x = 0, width = pred[i], 
                        height = widths[i], just = c("left", "center"), 
                        default.units = "native", gp = gpar(col = col[i], 
                         fill = fill[i]))
                    }
                    if (length(ycenter) > 1) 
                        grid.yaxis(at = ycenter, label = FALSE)
                            grid.text(ylevels, y = ycenter, x = unit(-1, "lines"), 
                            just = c("right", "center"), default.units = "native", 
                             check.overlap = TRUE)
                    grid.xaxis()
                }
            #############################################################
            }
            else {
                ycenter <- cumsum(pred) - pred
                for (i in 1:np) {
                    grid.rect(x = xscale[2]/2, y = ycenter[i], height = min(pred[i], 
                      ymax - ycenter[i]), width = widths[1], just = c("center", 
                      "bottom"), default.units = "native", gp = gpar(col = col[i], 
                      fill = fill[i]))
                }
                if (np > 1) {
                    grid.text(ylevels[1], x = unit(-1, "lines"), 
                      y = 0, just = c("left", "center"), rot = 90, 
                      default.units = "native", check.overlap = TRUE)
                    grid.text(ylevels[np], x = unit(-1, "lines"), 
                      y = ymax, just = c("right", "center"), rot = 90, 
                      default.units = "native", check.overlap = TRUE)
                }
                if (np > 2) {
                    grid.text(ylevels[-c(1, np)], x = unit(-1, "lines"), 
                      y = ycenter[-c(1, np)], just = "center", rot = 90, 
                      default.units = "native", check.overlap = TRUE)
                }
                grid.yaxis(main = FALSE)
            }
            grid.rect(gp = gpar(fill = "transparent"))
            upViewport(2)
        }
        return(rval)
    }
    

    And now we can test it!

    plot(ctree, terminal_panel = alt_node_barplot(ctree, horiz = TRUE))
    

    Here’s the output:

    enter image description here

    Just a few points:

    • I admit that this may not THE solution to your problem. It is merely a way of going about solving this type of problem, when easier options do not exist.

    • Don’t trust the function I gave above completely. As you can see, the beside parameter disables the horiz parameter automatically (my first edit) since I did not alter the sections of code that deal with beside being true. If you want it to work in this case, you’ll have to make those edits yourself – take a look at ?viewport and ?grid.rect to get started. I’m pretty sure the reverse function is also broken, but haven’t tested anything. Apologies to the original authors of the function if I butchered it a bit, this was merely meant to be a demonstration.

    I hope this helped a bit. Good luck with any further edits you need to make!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have the following regular expression that works fine in perl: Classification:\s([^\n]+?)(?:\sRange:\s([^\n]+?))*(?:\sStructural Integrity:\s([^\n]+))*\n The
I have been using the lib-svm binaries for classification of my data. For training
I have a multiclass svm classification(6 class). I would like to classify it using
So I have this huge tree that is basically a big switch/case with string
I have an sql query (MyQSL DB, using .Net's SqlClient) that returns a dataset.
I am using libsvm for music classification. I have chosen binary classification. In training
I start using NaiveBayes/Simple classifier for classification (Weka), however I have some problems to
I have been looking for a maximum entropy classification implementation which can deal with
Recently I started using Weka Explorer for classification problem. I have two types of
I have read stemming harms precision but improves recall in text classification. How does

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.