My aim is to create stacked bar chart with percent labels in ggplot. After some research and reading some material I've managed how to plot the chart I want. There a lot of material.
How do I label a stacked bar chart in ggplot2 without creating a summary data frame?
Create stacked barplot where each stack is scaled to sum to 100%
R stacked percentage bar plot with percentage of binary factor and labels (with ggplot)
However, I have 2 problems:
1) I can't find a proper place to put labels. You can see that labes are not centered and are in wrong sections. (plot generated not using shiny) How to solve this issue?
The second problem is when I try to use my plot code in shiny
.
I create labels using this function:
df$label = paste0(sprintf("%.0f", df$percent), "%")
, but when it is in reactive
I get an error. In real case I have more difficult data generaration and subseting example, so my data must be reactive
.
The best result I managed to get in shiny
.
Also, I enclose reproducable esample of the app.
My aim is to plot nice labels
for stacked percent bar chart
in ggplot
.
library(shiny)
library(shinydashboard)
library(plyr)
library(ggplot2)
# Header -----------------------------------------------------------
header <- dashboardHeader(title= "DashBoard")
# Sidebar --------------------------------------------------------------
sm <- sidebarMenu(
menuItem(
text="stacked bar chart",
tabName="chart",
icon=icon("eye")
)
)
sidebar <- dashboardSidebar(sm)
# Body --------------------------------------------------
body <- dashboardBody(
# Layout --------------------------------------------
tabItems(
tabItem(
tabName="chart",
fluidPage(
fluidRow(
title = "Inputs", status = "warning", width = 2, solidHeader = TRUE, collapsible = TRUE,
plotOutput("M1"),
dataTableOutput(outputId="M3")
)
)
)
)
)
# Setup Shiny app UI components -------------------------------------------
ui <- dashboardPage(header, sidebar, body)
# Setup Shiny app back-end components -------------------------------------
server <- function(input, output) {
# -----------------------------------------------------------------------------
#reproducable data generation
Mdata <- reactive({
set.seed(1992)
n=8
Category <- sample(c("Car", "Bus", "Bike"), n, replace = TRUE, prob = NULL)
Brand <- sample("Brand", n, replace = TRUE, prob = NULL)
Brand <- paste0(Brand, sample(1:14, n, replace = TRUE, prob = NULL))
USD <- abs(rnorm(n))*100
df <- data.frame(Category, Brand, USD)
# Calculate the percentages
df = ddply(df, .(Brand), transform, percent = USD/sum(USD) * 100)
# Format the labels and calculate their positions
df = ddply(df, .(Brand), transform, pos = (cumsum(USD) - 0.5 * USD))
#create nice labes
#df$label = paste0(sprintf("%.0f", df$percent), "%")
})
output$M1 <- renderPlot({
ggplot(Mdata(), aes(x=reorder(Brand,USD,
function(x)+sum(x)), y=percent, fill=Category))+
geom_bar(position = "fill", stat='identity', width = .7)+
geom_text(aes(label=percent, ymax=100, ymin=0), vjust=0, hjust=2, color = "white", position=position_fill())+
coord_flip()+
scale_y_continuous(labels = percent_format())+
ylab("")+
xlab("")
})
output$M3 <- renderDataTable({
Mdata()
})
# -----------------------------------------------------------------------------
}
# Render Shiny app --------------------------------------------------------
shinyApp(ui, server)