I'm trying to make a boxplot with ggvis and I can't seem to view one even with a simple example
library(dplyr)
library(ggplot2)
library(shiny) #I think this is required? not sure
data.frame(theVar = c(1,5:10,15)) %>% ggvis(x = ~theVar) #makes a histogram
data.frame(theVar = c(1,5:10,15)) %>% ggvis(x = ~theVar) %>% layer_boxplots()
Error: Can't find prop y.update
forcing a y variable:
data.frame(theVar = c(1,5:10,15)) %>% ggvis(x = ~theVar,y=~theVar) %>% layer_boxplots()
seems to turn it into intervals? not sure what its doing but it's not a boxplot, nor should a boxplot need an X and Y...
If you have a single variable, you have to use your variable for y and specify a dummy for x:
library(ggvis)
data.frame(theVar = c(1,5:10,15)) %>% ggvis(y = ~theVar, x = ~ 1) %>% layer_boxplots()
Related
I am creating this chart in highchart using the R package highcharter but it’s not working because the y axis is a character:
This is my code:
library(highcharter)
library(dplyr)
hchart(
mtcars %>% rownames_to_column("rowname"),
"scatter",
hcaes(x = mpg, y = rowname),
colorByPoint = TRUE
)
How can I create a chart like this?
As far as I get it from the docs we can't have a categorical variable on the y axis in case of scatter. However, a workaround would be to map an index on y then set the category labels via hc_yAsis:
library(highcharter)
library(tibble)
library(dplyr)
y_axis_categories <- rownames(mtcars)
mtcars %>%
rowid_to_column("id") %>%
mutate(id = id - 1) |> # JS indexing starts at 0
hchart(
"scatter",
hcaes(x = mpg, y = id),
colorByPoint = TRUE
) %>%
hc_yAxis(categories = y_axis_categories)
Please opine on how the order of the x axis on a Plotly bar chart can be arranged.
I am using a toy example with the diamond dataset and trying to arrange clarity by ascending mean depth. I am very familiar with ggplot but quite new to plotly. I have seen some postings online regarding this issue but none seem to be definitive. After rendering the plot, I think that the clarity categories are indeed ordered correctly, hovering the mouse to get the label values would suggest this, but these values (61.3, 61.3, 61.4, 61.6, 61.7,61.7,61.8, 61.9 for all clarity groups) don't obviously map to the y axis which is on a scale of 0 to 16k. This is confusing me. I am not looking to use the ggplotly wrapper, I am looking for a plotly solution, thanks.
library(tidyverse)
library(plotly)
set.seed(321)
my_diamonds <- ggplot2::diamonds %>%
slice(sample(nrow(.), 1000))
my_diamonds %>%
group_by(clarity) %>%
mutate(mean_depth = mean(depth)) %>%
ungroup() %>%
plot_ly(
data = .
, x = ~ clarity
, y = ~ mean_depth
) %>%
layout(
title = "Mean Depth for each Clarity Category"
, xaxis = list(categoryorder = "array", categoryarray = ~ reorder(clarity, mean_depth))
)
Data has not been processed fully prior to plotting. Once you select the appropriate information, your code plots fine. I have subtracted 61 from the mean_depth as it will be easier to see the bar order. You can remove the subtraction. Try this
set.seed(321)
my_diamonds <- ggplot2::diamonds %>%
slice(sample(nrow(.), 1000))
my_diamonds %>%
group_by(clarity) %>%
mutate(mean_depth = mean(depth)-61) %>%
distinct(clarity,mean_depth) %>% arrange(mean_depth) %>%
ungroup() %>%
plot_ly(
data = .
, x = ~ clarity
, y = ~ mean_depth
) %>%
layout(
title = "Mean Depth for each Clarity Category"
, xaxis = list(categoryorder = "array", categoryarray = ~ reorder(clarity, mean_depth))
)
I have the following code to create a simple column plot and it works fine:
library(highcharter)
d1 <- iris %>% group_by(Species) %>%
summarize(mean_sepal_width = mean(Sepal.Width))
highchart() %>%
hc_chart(type = 'column') %>%
hc_xAxis(categories = d1$Species) %>%
hc_add_series(data = d1$mean_sepal_width)
However, when I subset the input data such that only a single x variable exists, the x axis labels are broken:
d2 <- d %>% filter(Species == 'virginica')
highchart() %>%
hc_chart(type = 'column') %>%
hc_xAxis(categories = d2$Species) %>%
hc_add_series(data = d2$mean_sepal_width)
A potential solution is offered here (Highcharter bar chart cut off x axis label) but I prefer not to use the hchart() function since my actual plot is a lot more complicated.
Is there a way to fix these x axis labels?
Put d2$Species in a list (or use as.list). This is a known bug.
highchart() %>%
hc_chart(type = 'column') %>%
hc_xAxis(categories = as.list(d2$Species)) %>%
hc_add_series(data = d2$mean_sepal_width)
I am trying to make a boxplot in highchart to include it in a shiny app, along with another graph I already have.
The problem is that boxplot, as far as I can tell, do not behave like other plots and when you map a date to the x-axis, it is treated as a character string, this mean: the plot display the entire date ex: "2018-04-01" an not Apr'18 like it does in other plots.
Here I put a little reprex of what I have done
# Packages
library(tidyverse)
library(lubridate)
library(highcharter)
library(magrittr)
library(plotly)
# Data
stocks <- data.frame(
time = rep(as.Date('2009-01-01') + month(1:12), times = 10),
stock_price = rnorm(120, 0, 1)
)
# line plot
stocks %>%
group_by(time) %>%
summarise(mean_price = mean(stock_price)) %>%
hchart(.,
type = "line",
hcaes(x = "time",
y = "mean_price"))
# Box plot first try
# hchart boxplot
stocks %$%
hcboxplot(x = stock_price, time) %>%
hc_chart(type = "column")
After doing this first try, I try to create an abbreviated date and map it to the x-axis as follows, but the boxes are shown ordered alphabetically not chronologically
# hchart boxplot
stocks %>%
mutate(month = month(time, label = T),
year = str_extract(as.character(year(time)), "..$"),
time2 = paste(month, year, sep = "'")) %$%
hcboxplot(x = stock_price, time2) %>%
hc_chart(type = "column")
My desired output is a plot with x-axis like the line plot or like plotly's output
stocks %>%
group_by(time) %>%
plot_ly(x = ~time, y = ~stock_price, type = "box")
With the help of arrange() and fct_inorder(), I believe I've achieved your desired outcome:
stocks %>%
arrange(time) %>%
mutate(
month = month(time, label = T),
year = str_extract(as.character(year(time)), "..$"),
time2 = fct_inorder(paste(month, year, sep = "'"))
) %$%
hcboxplot(x = stock_price, time2) %>%
hc_chart(type = "column")
Using the following code:
library(ggvis)
library(dplyr)
mydf2 <- iris %>%
group_by(Species) %>%
summarize(Sepal.Length = mean(Sepal.Length),
Sepal.Width = mean(Sepal.Width))
mydf2 %>% as.data.frame() %>%
ggvis(x = ~ Species, y = ~ Sepal.Length ) %>%
layer_bars(fillOpacity := 0.1 ) %>%
add_axis("y", "ywidth", orient = "right", grid = FALSE) %>%
layer_lines(prop("y", ~ Sepal.Width, scale = "ywidth")) %>%
add_axis('x', title='the species', properties = axis_props(labels=list(fill='blank'))) %>%
add_axis('x', 'myx2', orient='bottom', title='') %>%
layer_lines(prop("x", ~ Species, scale = "myx2"), stroke := 'blank')
Output:
My issue is:
Does anyone know of a way to align the bar and line charts on this dual y-axes plot? I would like the tick marks to be aligned on the x-axis for both charts.
Edit
I decided to edit this question and provide a better example that shows better the problem.
After about 4 months and a bit of researching I found a way around this issue although it is kind of a hack:
mydf2 %>% as.data.frame() %>% mutate(Species2= as.numeric(Species)) %>%
ggvis(x = ~ Species2, y = ~ Sepal.Length ) %>%
layer_bars(fillOpacity := 0.1, width = 0.9 ) %>%
add_axis("y", "ywidth", orient = "right", grid = FALSE) %>%
layer_lines(prop("y", ~ Sepal.Width, scale = "ywidth")) %>%
add_axis('x', title='the species', properties = axis_props(labels=list(fill='blank'))) %>%
add_axis('x', 'myx2', orient='bottom', title='', grid=F) %>%
layer_lines(prop("x", ~ Species, scale = "myx2"), stroke := 'blank')
Output
The rational behind the above answer is that in order for the line and the bar chart to be aligned the x-axis needs to be numeric. So, I made a new categorical x-axis which is used to plot an invisible line (check last two lines of code). The result is not optimal but it works.
You could also check this answer too.
P.S. The example code for the question comes from this post on github. The above has (luckily) been raised as an issue there. If it gets fixed (or there is a way to fix this) I will update the answer.