Camford Oxbridge
Camford Oxbridge

Reputation: 894

Layout of main panel for plot

I want to get the following layout.

In my actual plots, the two plots in the third column are same x-axis and thus I exhibit them in one column.

enter image description here

The following example Shiny code has the three histograms with one column. So, we cannot observe how the most lowest histogram changes according to the bins. Thus I want to get the above layout.

enter image description here

Example Shiny Code

library(shiny)

# Define UI for application that draws a histogram
ui <- fluidPage(

    # Application title
    titlePanel("Old Faithful Geyser Data"),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            sliderInput("bins",
                        "Number of bins:",
                        min = 1,
                        max = 50,
                        value = 30)
        ),

        # Show a plot of the generated distribution
        mainPanel(
           plotOutput("distPlot1"),
           plotOutput("distPlot2"),

           plotOutput("distPlot3")

        )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

    output$distPlot1 <- renderPlot({
        # generate bins based on input$bins from ui.R
        x    <- faithful[, 2]
        bins <- seq(min(x), max(x), length.out = input$bins + 1)

        # draw the histogram with the specified number of bins
        hist(x, breaks = bins, col = 'darkgray', border = 'white')
    })




    output$distPlot2 <- renderPlot({
        # generate bins based on input$bins from ui.R
        y    <- faithful[, 2]
        bins <- seq(min(y), max(y), length.out = input$bins + 1)

        # draw the histogram with the specified number of bins
        hist(y, breaks = bins, col = 'darkgray', border = 'white')
    })








    output$distPlot3 <- renderPlot({
        # generate bins based on input$bins from ui.R
        z    <- faithful[, 2]
        bins <- seq(min(z), max(z), length.out = input$bins + 1)

        # draw the histogram with the specified number of bins
        hist(z, breaks = bins, col = 'darkgray', border = 'white')
    })






}

# Run the application 
shinyApp(ui = ui, server = server)

Please let me know any idea.


Edit for comment

I understand your idea. I do not use ggplot as follows;

x <- c(1, 2, 3, 4, 5)
y1 <- c(1, 1, 2, 3, 1)
y2 <- c(2, 2, 1, 2, 4)
y3 <- c(4, 3, 2, 1, 2)

split.screen(figs = c(1, 2))
split.screen(figs = c(2, 1), screen = 2)

screen(1)
plot(x, y1, type = "l")
screen(3)
plot(x, y2, type = "l")
screen(4)
plot(x, y3, type = "l")

The result is as follows;

enter image description here

Upvotes: 0

Views: 754

Answers (1)

KSONG01
KSONG01

Reputation: 59

I would use ggplot2 and gridExtra to arrange the plots. Here is the final output I got:

Screenshot

The main plots were done using grid.arrange to combine them together, and ggplot2 gives you more ability to control each of the subplots, named plot1, plot2, and plot3 in the codes, and plot2 and plot3 formed the 3rd column. Since your 3rd column has different x-axis, I added a second bin width to control them together. And, to make the program a bit more dynamic, I use renderUI and uiOutput to push the data information from the server back to ui to generate the two sliderInputs.

Codes:

library(ggplot2)
library(grid)
library(gridExtra)

# Define UI for application that draws a histogram
ui <- fluidPage(

    # Application title
    titlePanel("Old Faithful Geyser Data"),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            uiOutput("bins1"),
            uiOutput("bins2")
        ),

        # Show a plot of the generated distribution
        mainPanel(
            plotOutput("ggplot")
        )
    )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

    ## Your Data and give colnames for ggplot
    x    <- as.data.frame(faithful[, 2])
    y    <- as.data.frame(faithful[, 1])
    z    <- as.data.frame(faithful[, 1])
    colnames(x) <- "Count"
    colnames(y) <- "Count"
    colnames(z) <- "Count"

    ## Set bin size 1 and 2
    binWidth1 <- c(max(x))
    binWidth2 <- c(max(y))


    output$bins1 <- renderUI({
        sliderInput("bins1", 
                    h3("Bin width #1 "),
                    min = 1,
                    max = max(x),
                    value = (1 + max(x))/10)
    })

    output$bins2 <- renderUI({
        sliderInput("bins2", 
                    h3("Bin width #2 "),
                    min = 1,
                    max = max(y),
                    value = (1 +max(y))/10)
    })

    output$ggplot <- renderPlot({
        # bins <- seq(min(x), max(x), length.out = input$bins + 1)
        plot1 <- ggplot(x, aes(x = Count)) + 
            geom_histogram(binwidth = input$bins1, fill = "black", col = "grey")
        plot2 <- ggplot(y, aes(x = Count)) + 
            geom_histogram(binwidth = input$bins2, fill = "black", col = "grey")
        plot3 <- ggplot(z, aes(x = Count)) + 
            geom_histogram(binwidth = input$bins2, fill = "black", col = "grey")
        grid.arrange(grid.arrange(plot1), grid.arrange(plot2, plot3, ncol = 1), ncol = 2, widths = c(2, 1))
    })
}

# Run the application 
shinyApp(ui = ui, server = server)

Upvotes: 1

Related Questions