I am trying to plot frequency on a stacked barchart with the following code
x = data.frame(
Clinic = c('A','A','A','A','A','A','B','B','B','B','B','C','C','C','C'),
Doctor = c('Kooner','Halliday','Katz','Alizadeh','Patel','Baxter','Kooner','Halliday','Patel','Katz','Alizadeh','Baxter','Katz','Patel','Alizadeh'),
VisitDate = c('2014-06-01','2014-06-01','2014-06-15','2014-07-01','2014-07-01','2014-07-01','2014-07-01','2014-07-01','2014-07-01','2014-08-01','2014-08-01','2014-07-01','2014-08-01','2014-09-01','2014-08-01')
)
allDates = data.frame(VisitDate=c('2014-06-01','2014-06-15','2014-07-01','2014-07-15','2014-08-01','2014-08-15','2014-09-01'))
library(plyr)
visits = plyr::count(x[,c(1,3)])
visits1 = merge(allDates,visits, all.x = TRUE)
library(highcharter)
hc = highchart() %>%
hc_chart(type = "column") %>%
hc_yAxis(title = list(text = "Visits")) %>%
hc_xAxis(categories = allDates$VisitDate) %>%
hc_plotOptions(column = list(
dataLabels = list(enabled = FALSE),
stacking = "normal",
enableMouseTracking = TRUE)
) %>%
hc_series(list(name="Clinic-A",data=merge(allDates,visits1[visits1$Clinic == "A", ], all.x = TRUE)[,3]),
list(name="Clinic-B",data=merge(allDates,visits1[visits1$Clinic == "B", ], all.x = TRUE)[,3]),
list(name="Clinic-C",data=merge(allDates,visits1[visits1$Clinic == "C", ], all.x = TRUE)[,3])
)
hc
I can plot this with ggplot without much coercion. Is it possible to do this in the highcharter without too much coercion(for example the 4 merge statements). The answer to this post doesn't work for me.
library(ggplot2)
library(scales)
ggplot()+
geom_bar(aes(y = freq, x = as.Date(VisitDate), fill = Clinic),data = visits, stat = "identity")+
theme(legend.position = "bottom", legend.direction = "horizontal", legend.title = element_blank())+
scale_x_date(date_breaks = "1 month")+
scale_y_continuous(breaks = pretty_breaks())
hchart, used in dataframe is similar to qplot. hchart try to have the same behavior as qplot.
So, how about this?:
hchart(visits, "column", x = as.Date(VisitDate), y = freq, group = Clinic) %>%
hc_plotOptions(column = list(
dataLabels = list(enabled = FALSE),
stacking = "normal",
enableMouseTracking = TRUE)
)
Hope this help.
Related
Below you can see an example of the Pyramid population plot. This plot is prepared with ggplot2 and below you can see the plot.
library(ggplot2)
set.seed(1)
#create data frame
data <- data.frame(age = rep(1:100, 2), gender = rep(c("M", "F"), each = 100))
#add population variable
data$population <- 1/sqrt(data$age) * runif(200, 10000, 15000)
ggplot(data, aes(x = age, fill = gender,
y = ifelse(test = gender == "M",
yes = -population, no = population))) +
geom_bar(stat = "identity") +
scale_y_continuous(labels = abs, limits = max(data$population) * c(-1,1)) +
labs(title = "Population Pyramid", x = "Age", y = "Percent of population") +
coord_flip()
So now I want to do the same plot but with a Plotly package. I don't like to use ggplotly command and I tried to follow some examples but is not working :
plot_ly(data, x = population, y = age, group = gender, type = 'bar', orientation = 'h',
hoverinfo = 'y+text+name', text = abs_pop) %>%
layout(bargap = 0.1, barmode = 'overlay',
xaxis = list(tickmode = 'array', tickvals = c(-1000, -500, 0, 500, 1000),
ticktext = c('1000', '500', '0', '500', '1000')))
Can anybody help me with this problem and make this plot with Plotly.
You can use the following code:
library(plotly)
library(dplyr)
data %>%
mutate(population = ifelse(test = gender == "M", yes = -population, no = population)) %>%
mutate(abs_pop = abs(population)) %>%
plot_ly(x= ~population, y=~age, color=~gender) %>%
add_bars(orientation = 'h', hoverinfo = 'text', text = ~abs_pop) %>%
layout(bargap = 0.1, barmode = 'overlay',
xaxis = list(tickmode = 'array', tickvals = c(-15000, -10000, -5000, 0, 5000, 10000, 15000),
ticktext = c('15000', '10000', '5000', '0', '5000', '10000', '15000')))
Output:
Is there a way to change the order of subplots in plotly for R? Is there a way to manually change the levels of a factor in this code?
I want a plot with Weight in the first plot followed by a,b,c in order above it. But what I get as output is Weight, c, a and b as shown in the image graph
Here is my code
df<-data.frame("time"= seq(0.01,10,length.out=100),"Weight"=1:100, "a"=rnorm(100),"b"=rnorm(100),"c"=rnorm(100))
q <- df%>%
tidyr::gather(variable, value, -time) %>%
transform(id = as.integer(factor(variable))) %>%
plot_ly(x = ~time, y = ~value, color = ~variable, colors = "Dark2",
yaxis = ~paste0("y", id)
) %>%
layout(
xaxis = list(title = "Time,s",tickfont = list(size = 17),titlefont = list(size = 20)),
yaxis = list(tickfont = list(size = 17), title="DP"),
hoverlabel = list(font=list(size=20))
) %>%
add_lines() %>%
subplot(nrows = length(df)-1, shareX = TRUE)
One way to do this is re-ordering factor levels as below:
# set.seed to keep the exact same results
set.seed(123)
df<-data.frame("time"= seq(0.01,10,length.out=100),"Weight"=1:100, "a"=rnorm(100),"b"=rnorm(100),"c"=rnorm(100))
DF <- df%>%
tidyr::gather(variable, value, -time) %>%
transform(id = as.integer(factor(variable)))
DF$variable <- factor(DF$variable, levels = c("Weight", "a", "b", "c")) #re-order
q <- DF %>%
plot_ly(x = ~time, y = ~value, color = ~variable, colors = "Dark2",
yaxis = ~paste0("y", sort(id, decreasing =F))) %>% #sort the order
layout(
xaxis = list(title = "Time,s",tickfont = list(size = 17),titlefont = list(size = 20)),
yaxis = list(tickfont = list(size = 17), title="DP"),
hoverlabel = list(font=list(size=20))
) %>%
add_lines() %>%
subplot(nrows = length(df)-1, shareX = TRUE)
q
You will need sort(id, decreasing =F) to get exact same order of what you set in factor(DF$variable, levels = c("Weight", "a", "b", "c")).
Exchange the data, the name, and the line features of the top and bottom subplots as following code,
#assign q$x$data to one template variable p
p = q$x$data
#exchange the data, name, and line features of q$x$data[[1]] and q$x$data[[4]]
q$x$data[[1]]$x = p[[4]]$x
q$x$data[[1]]$y = p[[4]]$y
q$x$data[[1]]$name = p[[4]]$name
q$x$data[[1]]$line = p[[4]]$line
q$x$data[[4]]$x = p[[1]]$x
q$x$data[[4]]$y = p[[1]]$y
q$x$data[[4]]$name = p[[1]]$name
q$x$data[[4]]$line = p[[1]]$line
#show
q
The problem might have been caused by yaxis = ~paste0("y", id). I replaced it with yaxis = ~paste0(id, "y") to get the correct order. You may need to change some code to get the right format.
library(plotly)
df<-data.frame("time"= seq(0.01,10,length.out=100),"Weight"=1:100, "a"=rnorm(100),"b"=rnorm(100),"c"=rnorm(100))
q <- df%>%
tidyr::gather(variable, value, -time) %>%
transform(id = as.integer(factor(variable))) %>%
plot_ly(x = ~time, y = ~value, color = ~variable, colors = "Dark2",
yaxis = ~paste0(id, "y")
) %>%
layout(
xaxis = list(title = "Time,s",tickfont = list(size = 17),titlefont = list(size = 20)),
yaxis = list(tickfont = list(size = 17), title="DP"),
hoverlabel = list(font=list(size=20))
) %>%
add_lines() %>%
subplot(nrows = length(df), shareX = TRUE)
q
No matter what I do, I can not seem to find code to ensure the labels of my Pie chart, do not overlap the Pie chart OR other labels.
I've entered geom_text_repel and adjusted vjust size force x in various ways and nothing works. It works on some charts, and other charts it does not.
---
title: "Untitled"
date: "August 14, 2019"
output: html_document
---
```{r eval = TRUE, echo = FALSE, results = "asis", warning = FALSE, message = FALSE, fig.height = 6.25, fig.width = 12}
library(plyr)
library(dplyr)
library(kableExtra)
library(scales)
library(ggplot2)
library(RODBC)
library(data.table)
library(DT)
library(treemapify)
library(devtools)
library(digest)
library(plotly)
library(shiny)
library(ggrepel)
library(expss)
rptyear <- 2018
colours <- c("A" = "royalblue3", "B" = "red", "C" = "gold", "D" = "green4")
Category <- c("A", "B", "C", "D")
premiumtable <- cbind(rep(c("A","B","C","D"),11), c(rep(2009,4),rep(2010,4),rep(2011,4),rep(2012,4),rep(2013,4),rep(2014,4),rep(2015, 4), rep(2016,4), rep(2017,4), rep(2018,4),rep(2019,4)), as.numeric(c(13223284, 3379574,721217, 2272843,14946074,4274769, 753797,2655032, 15997384, 4952687, 722556,3035566,16244348,5541543,887109,3299966,15841630,6303443,1101696,3751892,14993295, 6993626,1312650,4158196,13946038, 7081457,1317428,4711389, 12800640, 6923012, 1345159, 4911780, 12314663, 6449919, 1395973,5004046,12612704,6968110,1507382,5745079,15311213,8958588,1849069,6819488)))
colnames(premiumtable) <- c("Var1", "Var2", "Freq")
currentPrem <- filter(as.data.table(premiumtable), Var2 == rptyear, Freq != 0)
prempie <- ggplot(currentPrem, aes(x="", y = as.numeric(currentPrem$Freq), fill= Var1))
prempie <- prempie + geom_bar(width = 1, stat = "identity", colour = "black")
prempie <- prempie + ggtitle(paste0("YTD Numbers:")) + coord_polar("y", start = 0)
prempie <- prempie + scale_fill_manual(values = colours)
prempie <- prempie + theme_void()+ theme(plot.title = element_text(face = "bold", size = 20, hjust = .5), legend.position = "none", axis.title=element_text(size=20), axis.title.y = element_blank(), axis.title.x = element_blank())
prempie <- prempie + geom_text_repel(mapping = aes(label = paste0(Var1, "\n $",prettyNum(round(as.numeric(currentPrem$Freq)/1000), big.mark = ",")) , x = 2),position = position_stack( vjust = .5), size = 6, force = 5,direction = "both", segment.size = 0)
```
Thanks for providing the working data/code. If you are open to using the package plotly it is quite good at producing pie charts right out of the box, and requires less fiddling about than ggplot. Here is an example with your data:
library(dplyr)
library(plotly)
#
rptyear <- 2018
colours <- c("A" = "royalblue3", "B" = "red", "C" = "gold", "D" = "green4")
# data
premiumtable <- data.frame(Var1 = rep(c("A","B","C","D"),11),
Var2 = c(rep(2009,4),rep(2010,4),rep(2011,4),rep(2012,4),rep(2013,4),rep(2014,4),rep(2015, 4),rep(2016,4), rep(2017,4),rep(2018,4),rep(2019,4)),
Freq = as.numeric(c(13223284, 3379574,721217, 2272843,14946074,4274769, 753797,2655032, 15997384, 4952687, 722556,3035566,16244348,5541543,887109,3299966,15841630,6303443,1101696,3751892,14993295, 6993626,1312650,4158196,13946038, 7081457,1317428,4711389, 12800640, 6923012, 1345159, 4911780, 12314663, 6449919, 1395973,5004046,12612704,6968110,1507382,5745079,15311213,8958588,1849069,6819488)))
# prepare plot data
currentPrem <-
premiumtable %>%
filter(Var2 == rptyear, Freq != 0) %>%
mutate(Freq = as.numeric(Freq))
# create plot labels
labels = paste0(currentPrem$Var1, "\n $",prettyNum(round(as.numeric(currentPrem$Freq)/1000), big.mark = ","))
# create plot
plot_ly(currentPrem,
labels = ~labels,
values = ~Freq, type = 'pie',
textposition = 'outside',
textinfo = 'label',
colors = colours) %>%
layout(title = paste("YTD Numbers:", rptyear),
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
showlegend = FALSE)
I have the following function:
library(highcharter)
hchart(
newdata,
"bar",
hcaes(
x = Gender,
group = is_churner,
y = Percent,
label = Nominal,
color = color
)
) %>%
hc_title(text = "") %>%
hc_yAxis(
title = list(text = ""),
labels = list(format = "{value}")
) %>%
hc_xAxis(title = list(text = "")) %>%
hc_tooltip(
pointFormat = "
Percent: {point.y:,.0f}%<br>
Nominal: {point.label:,.0f}<br>"
)
The function takes a dataframe such as the following:
newdata <- data.frame(
Gender = c(rep("Female", 2), rep("Male", 2)),
is_churner = c("Active", "Churner", "Active", "Churner"),
Nominal = c(7267L, 933L, 9767L, 1313L),
Percent = c(42.7, 41.5, 57.3, 58.5),
color = c("green", "red", "green", "red")
) %>%
dplyr::group_by(is_churner)
One of the columns - color is supposed to be mapped to the color argument of the hchart function. As far as I recall, this is something that used to work.
Now, however, I get a really ugly graph.
Neither the colors of the bars correspond to the colors column, nor the legend below (which is what the colors represent) are colored accordingly.
What am I doing wrong?
I believe the color has to be called separately outside hcaes, but your approach seems more intuitive/sensible, so shame it's not working. The following works:
hchart(
newdata,
"bar",
hcaes(
x = Gender,
group = is_churner,
y = Percent,
label = Nominal
), color = c("green", "red")
) %>%
hc_title(text = "") %>%
hc_yAxis(
title = list(text = ""),
labels = list(format = "{value}")
) %>%
hc_xAxis(title = list(text = "")) %>%
hc_tooltip(
pointFormat = "
Percent: {point.y:,.0f}%<br>
Nominal: {point.label:,.0f}<br>"
)
The following also works:
hchart(
newdata,
"bar",
hcaes(
x = Gender,
group = is_churner,
y = Percent,
label = Nominal
)
) %>%
hc_title(text = "") %>%
hc_yAxis(
title = list(text = ""),
labels = list(format = "{value}")
) %>%
hc_xAxis(title = list(text = "")) %>%
hc_tooltip(
pointFormat = "
Percent: {point.y:,.0f}%<br>
Nominal: {point.label:,.0f}<br>"
) %>%
hc_colors(c("green", "red"))
I've deleted color from hcaes and added it instead to hc_colors.
I have had the same issue, in my case it turned out that my css files overruled the colors I specified in the hchart color.
When I removed te relevant lines in the css files the color command did work in the way you originally specified. You do not need to call it separately outside hcaes.
library(tidyverse)
library(ggpubr)
df <- tibble(
iq = rnorm(150, 100, 15),
condition = rep(c("A", "B"), each = 75),
time = rep(c("t1", "t2", "t3","t1", "t2","t3"), each = 25)
)
ggbarplot(df,
x = "condition",
y = "iq",
fill = "time",
palette = "grey",
add = "mean_se", add.params = list(group = "time"),
position = position_dodge(0.8)) +
stat_compare_means(aes(group = time),label = "p.signif", paired = TRUE,
comparisons = list(c("t1", "t2"),
c("t1", "t3"),
c("t2", "t3")))
stat_compare_means() couldn't conduct pairwise comparison separately for each category.
Maybe this code could help:
You can calculate first the p-values for each comparisons and then add them to the plot.
library(tidyverse)
if(!require(devtools)) install.packages("devtools") devtools::install_github("kassambara/rstatix")
library(rstatix)
library(ggpubr)
stat.test <- df %>% group_by(condition) %>% t_test(iq ~ time) %>% adjust_pvalue() %>% add_significance("p.adj") %>% mutate(y.position = 115)
stat.test
ggbarplot(df,
x = "time",
y = "iq",
facet.by = "condition",
fill = "time",
palette = "grey",
add = "mean_se", add.params = list(group = "time"),
position = position_dodge(0.8)) + stat_pvalue_manual(stat.test,label = "p.adj", y.position = "y.position")