EDIT
This seems to be an issue already known to the plotly community
github plotly issue #689
and there is an analogous question here on SO.
Unfortunately, it seems no solution is available yet. Any advice would be greatly appreciated.
I am trying to use Crosstalk and Plotly to create a dashboard and I have come across an unexpected behaviour.
When selecting through the Crosstalk filter, the Plotly bargraph leaves "gaps" for the unselected entries.
As a reproducible example, let's say I want to compare cities populations, what I am getting is this (code at the bottom):
It might very well be that I am missing something, is there a way to get rid of the gap? any advice on viable ways to do a similar comparison avoiding the issue?
Thanks in advance.
Code:
---
title: "Crosstalk+Plotly bargraph selection"
---
```{r setup, include=FALSE}
options(stringsAsFactors = FALSE)
library(crosstalk)
library(dplyr)
library(plotly)
#data on cities' population
city_pop <- data.frame("City" = c("Florence", "Milan", "Venice"),
"Population" = c(382258, 1352000, 261905))
#setting up Crosstalk shared data
sd <- SharedData$new(city_pop, key = city_pop$city)
#filter for the cities
filt <- filter_select(
id = "select_name",
label = "Selected City",
sharedData = sd,
group = ~City)
#barplot of cities' population
bars_pop <- plot_ly(sd, x = ~City, y = ~Population) %>%
add_bars(width=0.2,
x = ~City,
y = ~Population,
color = I("#89CFF0"),
name = "",
opacity=.9,
hoverinfo = 'y',
hovertemplate = paste('%{x} <br> number of Residents: %{y}<extra></extra>')
)
```
```{r, echo=FALSE}
filt
bars_pop
```
This worked for me - on the axis where it's happening, set categoryorder = "trace".
e.g.,
plot_ly(...) %>% layout(yaxis = list(categoryorder = "trace"))
Related
I am trying the create a plotly gauge graph for a flexdashboard which should change value depending on the chosen filter in crosstalk::filter_select().
I have tried and tried but cannot get the filter to work. This is an example with mtcars of what I am trying to do. I noticed that if the SharedData object has only one value, then it works, but otherwise plotly does not show any data.
mtcars_data <- tibble::rownames_to_column(mtcars, "Car")
shared_mtcars <- SharedData$new(mtcars_data)
row1 <- bscols(filter_select("Car", "Car", shared_mtcars, ~Car, multiple = F)
)
fig <- plot_ly(shared_mtcars,
domain = list(x = c(0, 1), y = c(0, 1)),
value = ~mpg,
title = list(text = "MPG"),
type = "indicator",
mode = "gauge+number")
bscols(row1, fig, widths = 12)
This code results in a graph with no data. If I subset mtcars_data to take the first row or the first two rows (which happen to have the same value for mpg) then it works. If I subset rows 1 and 3, it doesn't.
I might be missing something - in that case would really appreciate any feedback.
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:
need some help and would be grateful for any advice. I want to create an interactive treemap in R. So far, so good, so bad. I managed that and was able to create an HTML widget, but when I open it, the legend isn't there anymore. In the original plot it is still there, but not as a saved file. I would be grateful for tips! this is my code:
library(tidyverse) library(readr) library(lubridate) library(ggthemes) library(treemap) library(d3treeR) library(readxl) library(htmlwidgets) df <- read_excel("df.xlsx")
Tidydata <- df %>% group_by(Level1, Level2, Level3) %>% summarise(Count = n())
tree <- treemap(Tidydata, index=c("Level1", "Level2", "Level3") ,vSize="Count" ,vColor="Count", type="value", border.col=c("black","white"), palette = "Greens", title="Treemap",
fontsize.title=16, fontsize.labels = 7, title.legend = "Counts" )
int <- d3tree(tree,width = "200%", height ="600px", rootname = "Level1")
saveWidget(int, file="TreePlot.html", selfcontained = T)
Update: I found out how to resolve the Problem with the missing legend and the overlapping issues.
If you are struggeling with the same issue, please use
int <- **d3tree2**(tree,width = "200%", height ="600px", rootname = "Level1")
instead of
int <- d3tree(tree,width = "200%", height ="600px", rootname = "Level1")
and you can create very nice interactive treemaps.
I'm trying to render a graph in a shiny app using highcharter that shares an x-axis (days) but has multiple y-axes (a percent and a count). After some research it seems like I should use the 'hc_yAxis_multiples' method. On the left y-axis, I have % displayed. On the right y-axis, I want the count displayed. There is a line graph that is based on the left y-axis (%), and a stacked bar graph that is displayed based on the right y-axis.
I have been able to overlay the two graphs, but the bar chart portion based on the right y-axis is not formatted to the corresponding y-axis. Based on what I have been looking at, it seems like something like this would produce a result that I want:
##This first block is to show what the data types of the variables I'm using are and what the structure of my df looks like
df$inbox_rate <- df$total_inbox / df$total_volume
df$inbox_rate <- round((df$inbox_rate*100),0)
df$received_dt <- as.character(df$received_dt)
df$received_dt <- as.Date(df$received_dt, "%Y%m%d")
df <- df[order(df$received_dt),]
## This second block here is where I'm trying to build the chart with two Y-axes
hc <- highchart()%>%
hc_title(text = paste(domain_name,sep=""),align = "center") %>%
hc_legend(align = "center") %>%
hc_xAxis(type = "datetime", labels = list(format = '{value:%m/%d}')) %>%
hc_yAxis_multiples(list(title = list(text = "IPR"),labels=list(format = '{value}%'),min=0,
max=100,showFirstLabel = TRUE,showLastLabel=TRUE,opposite = FALSE),
list(title = list(text = "Total Subscribers"),min=0,max = max(df$total_users),
labels = list(format = "{value}"),showLastLabel = FALSE, opposite = TRUE)) %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_add_series(df,"column",hcaes(
x=received_dt,y=total_users,group=isp,yAxis=total_users)) %>%
hc_add_series(df,type="line",hcaes(
x=received_dt,y=inbox_rate,group=isp,yAxis=inbox_rate)) %>%
hc_exporting(enabled = TRUE) %>%
hc_add_theme(thm)
hc
However this produces something that looks like this.
To give more insight about the data I'm using, the domain_name is a string variable that looks like this: example.com. The total_users variable is a number that varies from 0 to about 50000. The received_dt variable is a date, formatted using as.Date(df$received_dt, "%Y%m%d"). The inbox_rate variable is a percent, from 0 to 100.
The bar counts are all displaying to the full height of the graph, even though the values of the bars vary widely. To reiterate, I want the right y-axis that the bar chart heights are based on to be the count of the df$total_users. Within the hc_yAxis_multiples function, there are two lists given. I thought that the first list gives the left y-axis, and the second gives the right. The closest answer to my question that I could find was given by this stackoverflow response
If anyone has any insight, it would be very much appreciated!
Your use of the yAxis statement in hc_add_series seems to be off. First, it should not be inside hcaes and second, it's a number specifying which axis (in order of appearance in hy_yAxis_multiple call) the series belongs to. So hc_add_series(..., yAxis = 1) should be used to assign a series to the second (right) axis.
Below is a (fully self-explaining, independent, minimal) example that shows how it should work.
library(highcharter)
df <- data.frame(
total_inbox = c(2, 3, 4, 5, 6),
total_volume = c(30, 30, 30, 30, 30),
total_users = c(300, 400, 20, 340, 330),
received_dt = c("20180202", "20180204", "20180206", "20180210", "20180212"),
isp = "ProviderXY"
)
df$inbox_rate <- df$total_inbox / df$total_volume
df$inbox_rate <- round((df$inbox_rate*100),0)
df$received_dt <- as.character(df$received_dt)
df$received_dt <- as.Date(df$received_dt, "%Y%m%d")
df <- df[order(df$received_dt),]
hc <- highchart()%>%
hc_xAxis(type = "datetime", labels = list(format = '{value:%m/%d}')) %>%
hc_yAxis_multiples(list(title = list(text = "IPR"),labels=list(format = '{value}%'),min=0,
max=100,showFirstLabel = TRUE,showLastLabel=TRUE,opposite = FALSE),
list(title = list(text = "Total Subscribers"),min=0,max = max(df$total_users),
labels = list(format = "{value}"),showLastLabel = FALSE, opposite = TRUE)) %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_add_series(df,type="column",hcaes(x=received_dt,y=total_users,group=isp),yAxis=1) %>%
hc_add_series(df,type="line",hcaes(x=received_dt,y=inbox_rate,group=isp))
hc
Maybe take this as an example how code in questions should be like. Copy-Paste-Runnable, no outside variables and minus all the things that dont matter here (like the theme and legend for example).
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.