I'm working with choropleth map (ggplot2), i have problem implementing geom_text properly. In output it is showing text over map but i can see many repeated name, no idea why, and need help to fix that please. Using R studio, Australia map shape file and data in a csv file. Moreover I had intention to show values over map instead of state names, don't know how.
codes in UI.R file
library(shiny)
# Define UI for application
shinyUI(fluidPage(
# Application title
headerPanel("Unemployment rate Data"),
# Sidebar with controls to select the variable to plot against
# specify whether outliers should be included
sidebarLayout(
sidebarPanel(
selectInput("variable", "Type:",
c("States" = "region",
"Unemployment_Rate" = "unemployment_rate_2015"
)
)
#checkboxInput("outliers", "Show outliers", FALSE)
),
# Show the caption and plot of the requested variable against population data data
mainPanel(
h3(textOutput("caption")),
plotOutput("datPlot")
)
)#----/sidebar layout
))#----/shinyUI
codes in Server.R file
require(maptools)
require(ggmap)
require(maps)
require(mapproj)
require(data.table)
library(rgeos)
library(plyr)
library(shiny)
library(datasets)
library(ggplot2) # load ggplot
setwd("C:/Users/AbdullahAl/Documents/AU-Shapefile")
pop <- read.csv("unemployment.csv")
AUS = readShapeSpatial("AUS_adm1")
shinyServer(function(input, output) {
# Compute the forumla text in a reactive expression since it is
# shared by the output$caption and output$mpgPlot expressions
output$caption <- reactiveText(function(){
paste("States ~", input$variable)
})
# ggplot version
output$datPlot <- reactivePlot(function() {
pop <- data.table(States = pop$region, var = factor(pop[[input$variable]]))
# Generate a plot of the requested variable against year and only
# include outliers if requested
AUS <- fortify(AUS, region = "NAME_1")
#add color="black" inside geom_map to have the boarder black
ggplot() + geom_map(data = pop, aes(map_id = States, fill = var), map = AUS) +
expand_limits(x = AUS$long, y = AUS$lat) +
# to add values over
geom_text(data = AUS, aes(x =long , y = lat, label = id, size = 2.5),
check_overlap = TRUE, position = "jitter", parse = FALSE) +
geom_label()
# facet_wrap( ~ var) - use this to show each divided states
})
})
Link for .csv file
https://onedrive.live.com/redir?resid=15945AE760E741A4!2712&authkey=!AChRc_Cl_PjJ_I4&ithint=file%2ccsv
And the output as image
the image is showing Australis's map and repeated name of the states over it
Related
I've been building my first applications in shiny in order to publish them and share interactive graphs with my coworkers. At present I've been producing density plots to map behaviour. The Goal is to display between 1 and 4 plots as facets, depending on the "origin" selection and the "variable" selection in shiny. If I manually plot all 4 graphs, I get an output resembling this:
sampleplot <- data.frame("origin" = c("US","GB","GB","US","CA","US","GB","GB","US","CA","US","GB","GB","US","CA","US","GB","GB","US","CA"),
"variable" = c("p1","p2","p3","p1","p4","p1","p2","p3","p1","p1","p1","p2","p3","p1","p4","p1","p2","p3","p1","p1"),
"value" = runif(20, min = 0.2, max = 0.8))
sampleplot %>%
ggplot(aes(value, color = origin)) +
facet_wrap(~ variable, ncol = 2) +
geom_density()
However, in shiny, when you select "p1", and then subsequently "p2", "p3" or "p4", the plot changes for "p1" (not just because of the scale, the shape is altered). It happens with any combination of variables. I get a warning along those lines when that happens:
Warning in ==.default(variable, input$var) :
longer object length is not a multiple of shorter object length
I don't get what the issue is. The variable checkbox input is every type of variable listed, and each facet is essentially an individual subplot. So why does plotting the density of "p2" have an impact on the density of "p1". Would be great if anyone could shine some line on the problem for me.
I made a reproducible shiny app with the data and ggplot call provided, and taking the change in scale apart, nothing rare happens. Let me know if it helps. It would be helpful if you can provide some code of your app, so we know exactly what's going with your plot.
Example app:
library(shiny)
library(tidyverse)
sampleplot <- data.frame("origin" = c("US","GB","GB","US","CA","US","GB","GB","US","CA","US","GB","GB","US","CA","US","GB","GB","US","CA"),
"variable" = c("p1","p2","p3","p1","p4","p1","p2","p3","p1","p1","p1","p2","p3","p1","p4","p1","p2","p3","p1","p1"),
"value" = runif(20, min = 0.2, max = 0.8))
ui <- fluidPage(sidebarLayout(
sidebarPanel(selectInput('selection', "Select sampleplot's variable",choices = unique(sampleplot$variable), multiple = TRUE, selected = 'p1')),
mainPanel(plotOutput('sameplots'))
)
)
server <- function(input, output, session) {
reactive_sameplot <- reactive({
sampleplot %>%
filter(variable %in% input$selection) %>%
ggplot(aes(value, color = origin)) +
facet_wrap(~ variable, ncol = 2) +
geom_density()
})
output$sameplots <- renderPlot({reactive_sameplot()})
}
shinyApp(ui, server)
Is there a way to have a selectInput change two elements of a plot? For example below, I created a reactive block to manipulate the data I want to plot in geom_point for each selectInput choice and it works perfectly. However, I also want the color of the points to change, a different color for each choice that is automatic, the user need not choose one themselves. So for one input$case points I want what is written in geom_point "orangered2". But if they choose the other input$case option, I would like the points in geom_point to be "gold".
Maybe an if statement but I am not sure where to nest that if so.
I posted a snippet of my UI and server bits.
UI snippet from a tab
tabPanel("Analysis",
sidebarLayout(
sidebarPanel(width = 4,
selectInput(inputId = "case",
label="Locations",
choices = c("TRUE", "FALSE")))
Server snippet
server <- function(input, output){
data_use <- reactive({
real_final[real_final$case %in% input$case,]
})
output$bathy <- renderPlot({
autoplot.bathy(shelf, geom=c("raster", "contour")) +
scale_fill_gradientn(name = "meters above\nsea level", colours = c("plum2", "steelblue4","steelblue3", "steelblue2", "steelblue1"),
breaks = c(-6000,0),
limits = c(-6000,0),
labels = c("-6000m","0m"),
na.value = "black") +
geom_point(data = data_use(), aes(long, lat), color = "orangered2", pch = ".") +
xlab("Longitude") +
ylab("Latitude") +
ggtitle("Seal Locations") +
theme(axis.text.x=element_text(size=6),
axis.text.y=element_text(size=6),
axis.title=element_text(size=10,face="bold"))
An option is to return a list with a reactive conductor:
data_and_color <- reactive({
list(
data = real_final[real_final$case %in% input$case,],
color = ifelse(input$case == "TRUE", "gold", "orangered2")
)
})
Then in the renderPlot:
x <- data_and_color()
ggplot(data = x$data, ......)
color = x$color
I want to produce an application using R's shiny package. I would like to upload ggplots from another project and add some interactive content.
When I add a data point using geom_point() to a ggplot that was created in the same R code this works fine. However, when I save and re-read the ggplot again (*), an error occurs. I could still add the geom_point (**), but it does not accept the interactive content from input$slider.
ui.R
library(shiny)
shinyUI(
fluidPage(
# Title
titlePanel(""),
# sidebar
sidebarLayout(
sidebarPanel("",
sliderInput("slider", "slider",
min = 100, max = 500, value = 300, step = 10)
),
# Main
mainPanel("",
plotOutput("ggplt")
)
)
)
)
server.R
library(shiny)
shinyServer(
function(input, output){
# produce a plot
output$ggplt <- renderPlot({
# ggplot scatterplot
library(ggplot2)
gg <- ggplot(data = mtcars, aes(x = disp, y = mpg)) +
geom_point()
# (*) save ggplot
#saveRDS(gg, "plt.rds")
#rm(gg)
#gg <- readRDS("plt.rds")
# x-coordinate for geom_point
xc <- as.numeric(input$slider)
gg + geom_point(aes(x = xc, y = 20), size = 5, colour = "red")
## (**) alternative
#gg + geom_point(aes(x = 400, y = 20), size = 5, colour = "red")
})
}
)
I don't really know what is going on here, and I think it is probably some subtle interaction between the ggplot2 environment handling and the shiny reactive environment handling. It might be worth flagging as a bug.
However there are a number of ways to make it work with small changes. I think the best is to use a reactive function for the slider value, although just assigning xc with the frowned upon <<- also seems to work and is a smaller change.
You could also just use input$slider directly in the aes(..) function as that seems to work too, but using a reactive function feels cleaner.
So this is what I suggest as a workaround:
library(shiny)
library(ggplot2)
u <- shinyUI(
fluidPage(
titlePanel(""),
sidebarLayout(
sidebarPanel("", sliderInput("slider", "slider",
min = 100, max = 500, value = 300, step = 10)
),
mainPanel("", plotOutput("ggplt")
)
)))
s <- shinyServer( function(input, output){
sliderval <- reactive({input$slider})
output$ggplt <- renderPlot({
req(input$slider)
gg <- ggplot(data = mtcars) +
geom_point(aes(x = disp, y = mpg))
# (*) save ggplot
saveRDS(gg, "plt.rds")
rm(gg)
gg <- readRDS("plt.rds")
gg + geom_point(aes(x = sliderval(), y = 20), size = 5, colour = "red")
})
})
shinyApp(u,s)
yielding:
I am trying to change the background colors in US map for displaying presidential results for different states. I read so many posts regarding this color change but I was not able to change any of those colors. Below is my code, link for dataset and snapshot which I am getting:
#install.packages("ggplot2")
#install.packages("ggmap")
#install.packages("plyr")
#install.packages("raster")
#install.packages("stringr")
library(ggplot2) # for plotting and miscellaneuous things
library(ggmap) # for plotting
library(plyr) # for merging datasets
library(raster) # to get map shape filegeom_polygon
library(stringr) # for string operation
# Get geographic data for USA
usa.shape<-getData("GADM", country = "usa", level = 1)
# Creating a data frame of map data
usa.df <- map_data("state")
#rename 'region' as 'state' and make it a factor variable
colnames(usa.df) [5] <- "State"
usa.df$State <- as.factor(usa.df$State)
#set working directory
setwd("C:/Users/Ashish/Documents/Stats projects/2/")
#input data from file separated by commas
usa.dat <- read.csv("data1.csv", header = T)
# printing data structure
str(usa.df)
# removing % sign from the data, and converting percentage win to numeric
usa.dat$Clinton <- as.numeric(sub("%","",usa.dat$Clinton))/1
usa.dat$Trump <- as.numeric(sub("%","",usa.dat$Trump))/1
usa.dat$Others <- as.numeric(sub("%","",usa.dat$Others))/1
# Creating a winner column based on the percentage
usa.dat$Winner = "Trump"
usa.dat[usa.dat$Clinton > usa.dat$Trump,]$Winner = "Clinton"
usa.dat$State <- tolower(usa.dat$State)
# Creating a chance column which corresponds to winning percentage of the candidate
usa.dat$chance <- usa.dat$Trump
a <- usa.dat[usa.dat$Clinton > usa.dat$Trump,]
usa.dat[usa.dat$Clinton > usa.dat$Trump,]$chance <- a$Clinton
# display the internal structure of the object
usa.dat
#join the usa.df and usa.dat objects on state variable
usa.df <- join(usa.df, usa.dat, by = "State", type = "inner")
str(usa.df)
states <- data.frame(state.center, state.abb) # centers of states and abbreviations
#function for plotting different regions of USA map based on the input data showing different coloring scheme
#for each state.
p <- function(data, title) {
ggp <- ggplot() +
# Draw borders of states
geom_polygon(data = data, aes(x = long, y = lat, group = group,
fill = Winner, alpha=chance), color = "black", size = 0.15) +
#scale_alpha_continuous(range=c(0,1))+
scale_color_gradientn(colours = c("#F08080","white","#5DADE2"),breaks = c(0,50,100),
labels=c("Clinton","Equal","Trump"),
limits=c(0,100),name="Election Forecast") +
# Add state abbreviations
geom_text(data = states, aes(x = x, y = y, label = state.abb), size = 2)+
guides(fill = guide_legend(direction='vertical', title='Candidate', label=TRUE, colours=c("red", "blue")))
return(ggp)
}
figure.title <- "2016 presidential election result"
# Save the map to a file to viewing (you can plot on the screen also, but it takes
# much longer that way. The ratio of US height to width is 1:9.)
#print(p(usa.df, brks.to.use, figure.title))
ggsave(p(usa.df, figure.title), height = 4, width = 4*1.9,
file = "election_result.jpg")
Image link:
Dataset: Dataset link
I would like to get same coloring scheme as displayed in Election forecast gradient.
Thanks to Alistaire for providing his valuable feedbacks and solution for the above problem. Using scale_fill_brewer(type = 'qual', palette = 6) along with ggplot() resolves the above issue in R.
I'm using Rstudio and Shiny for the project.
I have defined a variable res and it contains dataframe with multiple rows and columns, then I make a plot and its x y and color are the data from res dataframe.
My problem is that when i Run it, if I write that i want x axis to be inputted variable values (input$SelInp), I dont get dataframe values, instead, I get only column name.
if I change the code to get the values directly from dataframe (res$some_column_name) I get the correct values.
ui.R
selectInput("SelInp",
label = "Choose one:",
choices = colnames(res)
)
server.R
output$plt = renderPlot({
qplot(data = res,
x = input$SelInp, #this only returns a column name
y = res$loan_amnt, # this returns correct values from column loan_amt
ylab = "some y axis",
xlab = "some x axis",
main="Our Chart")
}
)
so, I want to get the values in input$SelInp thanks in advance
I think the reason is that the selectInput is returning the column name as a character. qplot is expecting a variable. I didn't check if qplot has an option to use characters to specify scales but aes_string in ggplot does that:
ui.R
library(shiny)
library(ggplot2)
shinyUI(fluidPage(
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(sidebarPanel(
selectInput(
"selectedCol",
"Select colum for X axis",
choices = colnames(mtcars),
selected = colnames(mtcars)[1]
)
),
mainPanel(plotOutput("distPlot")))
))
server.R
library(shiny)
library(ggplot2)
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
x_axis <- input$selectedCol
gg <-
ggplot(mtcars, aes_string(x = x_axis, y = "hp", color = "cyl"))
gg <- gg + geom_point()
gg
})
})
Let me know if this helps.