Multiple variable observation plotly tooltip - r

I am working on making a plotly map of the US with hover tooltips which I have gotten to work somewhat. However, I have multiple observations per state for each variable I would like to display in the tooltip and currently only the first observation for each state is displayed. Each observation is the performance of a candidate in the 1976 presidential election in a state, and I would like the hover tooltip to display each candidates performance in the state instead of just the first candidate listed in that state.
Here is the code I am using at the moment.
candidate denotes the name of the candidate , state_share and round_share denote the percent of the state popular vote and state electoral votes the candidate receives respectively.
library(plotly)
colorscale <- c("blue" , "purple" , "red")
l <- list(color = toRGB("white"), width = 2)
# specify some map projection/options
g <- list(
scope = 'usa',
projection = list(type = 'albers usa'),
showlakes = FALSE
)
threshold10$hover <- with(threshold10, paste(state, "<br>" , canvec ,':',
state_share ,",","Electoral Votes", round_share ))
fig <- plot_geo(subset(threshold10, year == 1976), locationmode = 'USA-states')
fig <- fig %>%
add_trace(
z = ~evotes, text = ~ hover , locations = ~state_po,
color = ~state_share , colors = colorscale) %>%
layout(title = '1976 Electoral Vote Allocation <br> 10% State Threshold',
geo = g)
fig
I'm also attaching an image of the dataset and the map produced by my code. I appreciate any help anyone has to offer. I am newish to working with plotly and mapping so if this is a simple question sorry about that. Thank you for your help.
dataframe:
map output:

Related

How to show only some hoverinfo points on a line graph with Plotly in R

I have traffic and article dfs as follows:
library(plotly)
library(dplyr)
set.seed(101)
traffic <- data.frame(Date = seq(as.Date("2021-06-01"), as.Date("2021-07-10"), by="days"),
Views = round(rnorm(40, 5000, 200),0))
articleData <- data.frame(Date = as.Date(c("2021-06-01", "2021-07-04", "2021-07-10")),
article = c("Article 1", "Article 2", "Article 3"))
joinedData <- left_join(traffic, articleData)
I want to make a plotly line graph that shows a line for traffic, but for the 3 dates where there were articles published I would like to add a dot that the person can cover over and it will show what article was published that day. Below is what I was able to put together:
plot_ly(data = joinedData, x = ~Date, y = ~Views, type = "scatter", mode = "lines") %>%
add_trace(hoverinfo = "text", text = ~article, mode = "markers")
This technically works, but it puts a marker on every single day, not just the 3 days that had articles. Is there a way to ignore marking the days that don't have articles? I really just want to draw attention to the days that have articles published and show whether that article shows a spike in traffic or not.
I think you were really close in your question. I think you just need to filter your data for those three articles and create a new dataframe. You can use the new dataset in add_trace. This will only put points on the dates that had articles published.
library(dplyr)
library(plotly)
filteredJoinedData <- joinedData %>%
filter(article != "NA")
plot_ly(data = joinedData, x = ~Date, y = ~Views, type = "scatter", mode = "lines") %>%
add_trace(data = filteredJoinedData, hoverinfo = "text", text = ~article, mode = "markers")
Giving you this graph

Creating a Leaflet map in code workbook in Foundry

Anyone created a leaflet map in Code Workbook using r-Leaflet? I have a functioning script that runs (also double checked in R) but how do I get it to visualise and then use in a Report etc. I have tried various tweaks on what may get it to run but no success - any ideas
leaflet_map <- function(map_data) {
library(leaflet)
data<-map_data
# first cut the continuous variable into bins
# these bins are now factors
data$Fill_rateLvl <- cut(data$Fill_rate,
c(0,.5,0.6,0.7,0.8,0.9,1), include.lowest = T,
labels = c('<50%', '50-60%', '60-70%', '70-80%', '80-90%','90-100%'))
# then assign a palette to this using colorFactor
# in this case it goes from red for the smaller values to yellow and green
# standard stoplight for bad, good, and best
FillCol <- colorFactor(palette = 'RdYlGn', data$Fill_rateLvl)
m<-leaflet() %>%
addTiles() %>%
addProviderTiles(providers$CartoDB.Positron)%>%
setView(lng = -0, lat = 50, zoom = 8) %>%
addCircleMarkers(data = data, lat = ~lat, lng = ~long,
color = ~FillCol(Fill_rateLvl), popup = data$Lead_employer,
radius = ~sqrt(Fill_rate*50), group = 'Fill rate') %>%
addLegend('bottomright', pal = FillCol, values = data$Fill_rateLvl,
title = 'Fill rate for next two weeks',
opacity = 1)
return(NULL)
}
I am not familiar with R in code workbook, but it sounds to me that you need to materialize your leaflet map as a dataset and then consume it in some sort of map compatible UI.
For example slate has a map widget which is backed by leaflets. You can find documentation and examples for it in https://www.palantir.com/docs/foundry/slate/widgets-map/

Selecting point with shiny and plotly

I have been trying for some time to debug my Shiny gadget but still cannot manage it. Really appreciate any help.
My gadget consists of a scatterplot generated with Plotly. The user can click one of the points, which will allow you to change some parameters associated with that point. To emphasise the fact that the user has selected that point, I wanted to highlight the selected point.
Alternatively, the user can also select a point from a dropdown menu, which also should highlight the corresponding point.
As an added feature, I want to additionally highlight points that are below a certain threshold on the x axis. This threshold is represented by a dotted line, which you can turn on and off, and move the value of the threshold.
In summary, the points on the plot should all be blue circles, except for the following two cases:
if it is clicked, i.e. it is the "active point" (this should create a red border around the point)
if it is below the threshold on the x-axis (the point should turn to an orange square)
If it is active AND below the threshold, it should be an orange square with a red border, as you would expect.
My gadget works, kind of. But in some cases not. In the example below, one of the points is already below the threshold, but when I select that point, the red marker appears on another point! Despite the active variable being the correct one.
I also get a weird behaviour that the points turn purple if the threshold is below all of the points. But if I move the threshold to be above one of the points, the colours are corrected.
I have a suspicion that this is something to do with the points being on different traces? Therefore when I try to highlight certain points, perhaps I am not indexing the vector as I am expecting. But I am finding it really difficult to debug inside Shiny and Plotly, and I have no good understanding of the Plotly object, so I don't have much clue as to what is going on.
The code below is a reproducible example. You have to run "dat1" through the "rew8r" function. I have taken out other features of the app to try to focus on the problem. Thanks very much to anyone who might take the time to have a look at this, and give any hints!
library(plotly)
library(dplyr)
library(shiny)
library(reactable)
dat1 <- data.frame(
Indicator = c("v1","v2","v3"),
Weight = rep(1,3),
Correlation = c(0.1, 0.8, 0.6) )
rew8r <- function(dat){
# get indicator names
inames <- dat$Indicator
## Create the shiny UI layout
ui <- fluidPage(
# the side panel
sidebarPanel(
selectInput("vseldrop", "Select indicator here or by clicking a point on plot.",
c("<Select>",inames)),
hr(style = "border-top: 1px solid #000000;"),
fluidRow(
column(6,numericInput("locorval", "Low correlation threshold:", 0.2, min = -1, max = 1, step = 0.05)),
column(6,br(),checkboxInput("locorsw", "Enable", value = FALSE)))
),
# the main panel (graph, table, etc)
mainPanel(
plotlyOutput("corrplot"),
textOutput("info")
)
)
## Create the Shiny Server layout
server <- function(input, output, session) {
# this is the plotly click data
event.data <- reactive({event_data(event = "plotly_click", source = "scplot")})
# First, monitor which variable is active
# Create reactive value for active var
acvar <- reactiveVal(NULL)
# update active variable via plot click
observeEvent(event.data(),{
acvar(event.data()$key)})
# update active variable via dropdown
observeEvent(input$vseldrop,
acvar(input$vseldrop))
## Create the plotly plot that compares price vs scoops
output$corrplot <- renderPlotly({
# colours around markers when selected or not
lincol <- ifelse(inames %in% acvar(), "red", "blue")
# size of line around marker (set to 0 if not selected)
linsize <- ifelse(inames %in% acvar(), 3, 0)
# symbol when above/below corr threshold
symbs <- if(input$locorsw==TRUE){c(16,15)}else{c(16,16)}
# colour when above/below threshold
pcols <- if(input$locorsw==TRUE){c("blue", "orange")}else{c("blue", "blue")}
# generate main plot
p <- plot_ly(dat, x = ~Correlation, y = ~Weight, type = "scatter", mode = "markers",
text = ~Indicator, key = ~Indicator, source = "scplot",
marker = list(size = 10, line = list(color = lincol, width = linsize)),
symbol = ~Correlation < input$locorval, symbols = symbs,
color = ~Correlation < input$locorval, colors = pcols) %>%
layout(showlegend = FALSE, yaxis = list(
range = c(0, 1.25),
autotick = FALSE,
dtick = 0.25),
xaxis = list(
range = c(-0.5, 1),
autotick = FALSE,
dtick = 0.2))
# add low correlation line, if activated
if(input$locorsw==TRUE){
p <- p %>% add_segments(x = input$locorval, xend = input$locorval, y = 0, yend = 1.25,
marker = list(color = 'red', opacity=0),
line = list(dash = 'dash')) %>%
layout(showlegend = FALSE)
}
p
})
# Text info
output$info <- renderText({
paste(acvar(), class(acvar()))
})
# update dropdown menu
observeEvent(acvar(),{
updateSelectInput(session, "vseldrop", selected = acvar())
})
}
runGadget(ui, server, viewer = browserViewer())
}

Chloropleth graph colours in the wrong countries

Bit of a strange problem using the leaflet package on R. I'm trying to colour in certain countries depending on how many users are in those countries. Everything goes well, except the countries are being coloured in with the wrong data. So for example, Morocco is being coloured in as if it were Jordan, etc.
I'm working with this free world map shapefile: http://thematicmapping.org/downloads/world_borders.php
When I draw a map with only the data included with the shapefile (data$POP2005), everything is fine. So perhaps there is a problem with my join?
user_data table:
NAME USERS
Morocco 250
Jordan 1000
Canada 5007
Code used:
world <- readOGR(dsn=path.expand("~/TM_WORLD_BORDERS_SIMPL-0.3"),
layer="TM_WORLD_BORDERS_SIMPL-0.3")
world#data <- merge(world#data, user_data, by="NAME", all.x = TRUE)
pal <- colorBin("YlOrRd", domain = world#data$USERS, bins = 5)
m <- leaflet(world) %>%
addTiles() %>%
addPolygons(
fillColor = ~pal(world#data$USERS),
weight = 2,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7)
m
When I try the code above, Morocco is showing as 1000 users (the result Jordan should have). Other countries are similarly incorrect. What am I doing wrong?
Many thanks!
I think that by merging world#data with itself is causing some strange interactions that are hard to track down (for example, in my first attempt Morocco was fine but Cuba was red). Instead I used sp::merge from the sp package which allowed me to simplify my code a bit:
library(rgdal)
library(leaflet)
user_data <- data.frame(NAME = c("Morocco", "Jordan", "Canada"),
USERS = c(250, 1000, 5007))
world <- readOGR(dsn="TM_WORLD_BORDERS_SIMPL-0.3.shp",
layer="TM_WORLD_BORDERS_SIMPL-0.3")
world_merged <- sp::merge(world, user_data)
pal <- colorBin("YlOrRd", domain = world_merged$USERS, bins = 5)
m <- leaflet(world) %>%
addTiles() %>%
addPolygons(
fillColor = ~pal(world_merged$USERS),
weight = 2,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.7)
m
And yielded this leaflet map (zoomed in here):

plotting barchart in popup using leaflet library

Quick question all.
I have some data in sql server which i have loaded into RStudio. I have made a barchart for the data and now i am using leaflet library with the use of latitude and longitude to plot a point on the map. I want to be able to use popup to show a barchart in it when the user clicks on the point.
BarChart code (maybe this is a problem because i am using googleVis library so not sure if i can use this in the popup. but again this is the most appropriate bar graph i can make and need- other suggestions could be helpful as i am not a professional in R libraries yet)
Switzerland <- sqlQuery(con, "sql query")
SwitzerlandChart <- gvisBarChart(Switzerland, options = list(height=200))
For the graph plot the code is:
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addCircles(lng=8.498868, lat=46.9221, popup=paste(plot(SwitzerlandChart)))
When i run this code it opens a webpage to view my barplot.
Then i run the following:
m #Prints the graph
This prints the graph with the point in the desired location but the popup shows me a webpage instead which also only i can open.
I want to be able to plot the bargraph inside the popup please.
Hope someone can help
Maybe a little late but here's a solution. The addPopups() function in library(leaflet) seems to be able to handle .svg files. Therefore, you could simply save your plot using svg() and then read it again using readLines(). Here's a reproducible example using library(mapview):
library(lattice)
library(mapview)
library(sp)
data(meuse)
coordinates(meuse) <- ~x+y
proj4string(meuse) <- CRS("+init=epsg:28992")
clr <- rep("grey", length(meuse))
fldr <- tempfile()
dir.create(fldr)
pop <- lapply(seq(length(meuse)), function(i) {
clr[i] <- "red"
p <- xyplot(meuse$cadmium ~ meuse$copper,
col = clr, pch = 20, alpha = 0.7)
svg(filename = paste(fldr, "test.svg", sep = "/"),
width = 250 * 0.01334, height = 250 * 0.01334)
print(p)
dev.off()
tst <- paste(readLines(paste(fldr, "test.svg", sep = "/")), collapse = "")
return(tst)
})
mapview(meuse, popup = pop, cex = "cadmium")
You will see that each popup is a scatterplot. As for a leaflet example, consider this:
content <- pop[[1]]
leaflet() %>% addTiles() %>%
addPopups(-122.327298, 47.597131, content,
options = popupOptions(closeButton = FALSE)
)
In case you need the plot to be interactive, you could have a look at library(gridSVG) which is able to produce interactive svg plots from e.g. lattice or ggplot2 plots.
UPDATE:
library(mapview) now has designated functionality for this:
popupGraph: to embed lattice, ggplot2 or interactive hatmlwidgets based plots.
popupImage: to embed local or remote (web) images
This is currently only available in the development version of mapview which can be installed with:
devtools::install_github("environmentalinformatics-marburg/mapview", ref = "develop"
This may be a little late too, but here is a full leaflet implementation. I first create the plot and then use the popupGraph function to add it in.
# make a plot of the two columns in the dataset
p <- xyplot(Home ~ Auto, data = Jun, col = "orange", pch = 20, cex = 2)
# make one for each data point
p <- mget(rep("p", length(Jun)))
# color code it so that the corresponding points are dark green
clr <- rep("orange", length(Jun))
p <- lapply(1:length(p), function(i) {
clr[i] <- "dark green"
update(p[[i]], col = clr)
})
# now make the leaflet map
m1 <- leaflet() %>%
addTiles() %>%
setView(lng = -72, lat = 41, zoom = 8) %>%
# add the markers for the Jun dataset
# use the popupGraph function
addCircleMarkers(data = Jun, lat = ~Lat, lng = ~Lon,
color = ~beatCol(BeatHomeLvl), popup = popupGraph(p),
radius = ~sqrt(BeatHome*50), group = 'Home - Jun') %>%
# layer control
addLayersControl(
overlayGroups = c('Home - Jun'
),
options = layersControlOptions(collapsed = F)
) %>%
# legend for compare to average
addLegend('bottomright', pal = beatCol, values = last$BeatTotalLvl,
title = 'Compare<br>Quote Count to<br>3Mos State Avg',
opacity = 1)
m1
Here is the output.

Resources