ggvis plot with error bars - custom axis text - r

I am trying to create a ggvis plot with error bars. I decided to plot mean values as points and error bars as rectangles. Here is my data set:
mivector<-c(1.5,2,2.5,2,2.5,3,2.5,3,3.5)
treats<-c("A","A","A","B","B","B","C","C","C")
library(ggvis)
library(dplyr)
plotdf<-data.frame(mivector,treats)
plotdf<- plotdf %>% group_by(treats) %>%
summarise(mimean=mean(mivector),misd=sd(mivector)) %>%
mutate(milow=mimean-misd,mihigh=mimean+misd,mileft=as.numeric(treats)-0.005,miright=as.numeric(treats)+0.005,treatsno=as.numeric(treats)) %>%
select(-misd)
And here is the plotting code I am trying to make:
plotdf %>% ggvis() %>% layer_points(~treatsno,~mimean) %>%
layer_rects(prop("x",~mileft),prop("y",~milow),prop("x2",~miright),prop("y2",~mihigh),fillOpacity:=1) %>%
scale_numeric("y", domain = c(0, 5)) %>%
add_axis("y",grid=F) %>%
add_axis("x",ticks=length(plotdf$treats),grid=F,properties=axis_props(labels=list(text=c("a","b","c"))))
I got stuck at the point that I cannot assign labels to the axis ticks properly. Instead of having 3 ticks with the text "a", "b" and "c" correspondingly, I have "a,b,c" for every tick.
Could you please indicate what I am doing wrong? Maybe there is generally a much easier way to make error bars which I am not aware of?
Thank you in advance!

Related

gg-plot isnt producing bars on the Bar chart

I have used the following code
ggplot(IncomeGroup_count,
aes(x=Income_Group,
y= Percentage,
colour = 'lightblue'))
But the only thing it produces is the x and y axis with no bars.
It looks like you are missing the geom_bar function. Typically ggplot works as the base function for fitting whatever data you are using and then the geom functions "draw" the plot using that data. Here I have constructed a bar plot using data in R since you have not supplied your own data in your question.
#### Load Library ####
library(tidyverse)
#### Plot ####
airquality %>%
ggplot(aes(x=is.na(Ozone)))+
geom_bar()
Which gives you this bare bones bar plot. It takes the NA values from the airquality dataset, then draws bars thereafter plotting the NA values by "TRUE" for NA and "FALSE" for not NA:
Edit
Again it's difficult to guess what is going wrong if you don't share your data, so I'm assuming based off your comments below that you are trying to plot y explicitly as a count. As suggested in the comments, geom_col may be better for this. Using a different example from the same dataset:
airquality %>%
group_by(Month) %>%
summarise(Mean_Ozone = mean(Ozone, na.rm=T)) %>%
ggplot(aes(x=Month,
y=Mean_Ozone))+
geom_col()
You get this:

Aligning groups of points and of boxplots in ggplotly

I am trying to interactively show both points and boxplots of the same data in a ggplotly situation.
"dodged" positioning does the job in ggplot, but when passing to plotly positioning goes off--how do I get boxes and points to line up? (Essentially throwing points on top of this question. I also realize that an answer to this question would likely also be an answer to my question, though there may be more answers for my issue.)
What I want is for both layers to show up together, even when a group is missing at a location (either centered or in the group location), for examply like so:
What I get with interactivity so far is this:
library(plotly)
mtcars_boxplot <- mtcars %>%
mutate(cyl=as.factor(cyl)) %>%
mutate(vs=as.factor(vs)) %>%
ggplot(aes(y=mpg, x=cyl)) +
geom_boxplot(aes(color=vs), position=position_dodge())+
geom_point(aes(color=vs), position=position_jitterdodge(), size = 0.5)
mtcars_boxplot %>%
ggplotly() %>%
layout(boxmode='group')
You can see that for cyl=8, the points are centered, but the box shows up in its group's location.
My question is: how do I get an interactive version of the first image, or something similar (preferably using ggplotly)?
I found a way to do this--not with ggplot, but pure plotly:
mtcars_boxplot <- mtcars %>%
mutate(cyl=as.factor(cyl)) %>%
mutate(vs=as.factor(vs)) %>%
plot_ly(type="box",
x = ~cyl,
y = ~mpg,
color = ~vs,
alignmentgroup = ~MOTART,
boxpoints = "all",
pointpos = 0,
jitter = 1) %>%
layout(boxmode='group')
If there is a ggplotly-answer, I would still love to know that one. (This actually ends up aligning more nicely, but is also more work when working in ggplot otherwise.)

Various variables (y-axis) in the same graph grouped by factors in R?

I have a problem making a graph in R. I have the following data, with flower type, and a color index for different points (distance_petal).
flower_type<-c(rep("blue",3),rep("red",3))
distance_petal1<-c(2,3,2,7,6,7)
distance_petal2<-c(2,2,1,8,6,8)
distance_petal3<-c(1,1,2,9,9,8)
data<-as.data.frame(cbind(flower_type,distance_petal1,distance_petal2,distance_petal3))
data$flower_type<-as.factor(flower_type)
I am trying to make a graph showing distance_petal1, distance_petal2 and distance_petal3 in the X-axis, and the value in the Y-axis. So I want to obtain 2 lines, one for each flower type with 3 points in the Y-axis.
I mean, I want to make something like this, but instead of plotting all values, just plotting the mean for each variable for each factor.
library(GGally)
ggparcoord(data,
columns = 2:4, groupColumn = 1,scale="globalminmax"
)
Does anyone know how to do this?
Thank you very much in advance, have a nice day!
Using ggplot, dplyr and tidyr you can try:
Not sure if your question asks for a line as in the example from GGally or if you want points as in the question. So have included both the line and point version you can just remove the line of ggplot code to get what you need.
library(dplyr)
library(tidyr)
library(ggplot2)
data %>%
pivot_longer(-1) %>%
mutate(value = as.numeric(value))%>%
group_by(flower_type, name) %>%
summarise(mean = mean(value)) %>%
ggplot(aes(name, mean, colour = flower_type))+
geom_line(aes(group = flower_type))+
geom_point()
Created on 2021-04-25 by the reprex package (v2.0.0)

ggvis barplot: negative values

I'm trying to draw a barplot using ggvis, for some data where for each variable I have both a negative and a positive value. It would be similar to this example from ggplot2.
However, when I try something similar in ggvis, I end up with basically no plot at all, just some weird lines.
Example data:
df <- data.frame(
direction=rep(c("up", "down"), each=3),
value=c(1:3, -c(1:3)),
x=rep(c("A", "B", "C"), 2))
This works, for all positive values:
df %>%
mutate(value.pos=abs(value)) %>%
ggvis(x=~x, y=~value.pos) %>%
group_by(direction) %>%
layer_bars(stack=TRUE)
This gives me nothing:
df %>%
ggvis(x=~x, y=~value) %>%
group_by(direction) %>%
layer_bars(stack=TRUE)
I've also tried various combinations of plotting them one by one, e.g.:
df %>%
spread(key=direction, value=value) %>%
ggvis(x=~x, y=~up) %>%
layer_bars() %>%
layer_bars(x=~x, y=~down)
So far, no luck. I suspect I'm missing some simple solution...
I don't ggvis lets you produce stacked bar plots with negative values within the same groups as positive data.
This is because if an x value appear more than once in the data, then ggvis will sum up the y values at each x. I had thought that since you plotted the vector 1:3, they canceled out, but that's not the case.
As of now, I do not believe that dodged bar plots exist for this. It also messes with the labels.
You can produce the plot non-stacked, while filling in the position.
df %>%
group_by(direction) %>%
ggvis(x=~x, y=~value, fill = ~direction) %>%
layer_bars(stack = FALSE)
Anyways, you might consider avoiding ggvis for any production work since it is under development, and hasn't been updated in a couple of months.
#shayaa
Thanks, this does seem to be working, although it will probably require some tweaking, and may not look as nicely as if I was using ggplot2. Actually, the reason I am using ggvis, is because I would like to combine it with shiny, to make a small interactive web version. For example:
df <- data.frame(
direction=rep(c("up", "down"), each=3),
value=c(1:3, -c(1:3)),
x=rep(c("A", "B", "C"), 2))
plot_fct <- function(letter) {
df %>%
filter(x==letter) %>%
ggvis(x=~x, y=~value, fill = ~direction) %>%
layer_bars(stack = FALSE) %>%
scale_numeric("y", domain=c(NA,NA))
}
ui <- fluidPage(
sidebarPanel(
selectInput("letter", "Choose letter", c("A", "B", "C"), selected="A")
),
mainPanel(
ggvisOutput("letter_barplot")
)
)
server <- function(input, output) {
plot_fct(letter=reactive(input$letter)) %>% bind_shiny("letter_barplot")
}
runApp(shinyApp(ui, server))
However, it does not seem to work for me anyway, since there is some issue with the reactive being of class character. I keep getting the error:
Error in eval(substitute(expr), envir, enclos) :
comparison (1) is possible only for atomic and list types
Guess I'll have to keep trying.

Lines stroke (color) as legend and moving legend labels next to lines

I'm trying to use ggvis to make a plot similar to this one
and I'm running into two issues.
First, I've tried assigning the line stroke color as the legend shape but ggvis always keeps the circles. In addition, it doesn't recognize the dashed lines either.
library(ggvis)
data <-data.frame(region=rep(c("A","B","C"),5),c=rep(seq(1980,2000,5),3), val=rnorm(15))
data %>%
group_by(region) %>%
ggvis(~c, ~val) %>%
layer_smooths(stroke=~region, strokeDash = ~region,strokeWidth := 3, strokeOpacity := 0.65) %>%
add_axis("y", title="y") %>%
add_axis("x", title="y", format=####) %>%
add_legend(c("stroke","strokeDash")) ## Adding this does not update the legend to recognize the line color or dashes.
Some asked something here but no one answered.
Finally, I'd like to place the legend names of each region next to the lines just as in the first graph. For this, I haven't found out how to even start.
Any help is appreciated.
UPDATE:
I asked how to have x axis labels as numeric and the answer was adding format = "####" to add_axis.
I didn't manage to find what I needed specifically, but I found a partial solution. See the comments in the code.
data <-data.frame(region=rep(c("A","B","C"),5),c=rep(seq(1980,2000,5),3), val=rnorm(15))
data$region2 <- data$region ## create an additional region variable
data$region2 <- as.character(data$region2)
data$region2[data$c != 2000] <- "" ## Fill every year which is not the last year to be an empty character vector
data %>%
group_by(region) %>%
ggvis(~c, ~val) %>%
layer_smooths(stroke=~region, strokeDash = ~region,strokeWidth := 3, strokeOpacity := 0.65) %>%
layer_text(text := ~region2) %>% ## add this new region variable, which will only write over the last year.
add_axis("y", title="y") %>%
add_axis("x", title="y", format="####") %>%
hide_legend(c("stroke","strokeDash"))

Resources