I need to get a scatter plot like this based on 2 categorical variables where each variable has 2 levels.
I am using ggvis package in R.
This is my code so far
salab<- read.table("http://users.stat.ufl.edu
/~rrandles/sta4210/Rclassnotes/data/textdatasets/KutnerData/
Chapter%2022%20Data%20Sets/CH22TA06.txt", quote="\"", comment.char="")
salab %>% ggvis(~V2, ~V1, fill = ~factor(V3*V4)) %>% layer_points()
Which is incorrect because i need 4 factors combinations. Can anyone help me to figure out what modification should i do ?
I think you need factor(V3):factor(V4) instead of factor(V3*V4):
salab %>%
ggvis(~V2, ~V1, fill = ~ factor(V3):factor(V4)) %>%
layer_points()
An alternative:
salab$`V3*V4`<-paste0("V3=",salab$V3,"*","V4=",salab$V4)
salab %>% ggvis(~V2, ~V1, shape = ~`V3*V4`) %>% layer_points()
Related
I have two ggplot2 that I want to transform to ggplotly with the idea of interaction between both figures.
The problem is that the DF for the second needs a transformation. I know how to do it with plotly from scratch but I need do it from ggplot2.
Here is my code:
require(dplyr)
require(lubridate)
require(ggplot2)
require(gridExtra)
require(plotly)
My data:
df1<-tibble(date=seq.Date(as.Date("2000-01-01"),as.Date("2003-12-31"),by="1 month"),
value=sample(10:20,48,replace = TRUE))
df2<-df1 %>% mutate(year=year(date))
df3<-df2 %>%
group_by(year) %>%
summarise(max=max(value),mean=mean(value),min=min(value))
This is the final output with ggplot2 without interaction
graf1<-ggplot(df2)+geom_line(aes(date,value,color=factor(year),group=year),size=4)
graf2<-ggplot(df3)+
geom_segment(aes(x=year,xend=year,y=min,yend=max,color=factor(year),group=year),size=10)+
geom_point(aes(year,mean),size=2)
grid.arrange(graf1,graf2,nrow=2)
This is the my proposal to do it from ggplot2 to ggplotly (and doesn't work)
df2Linked<-highlight_key(df2,~year)
graf1<-ggplot(df2Linked)+geom_line(aes(date,value,color=factor(year),group=year),size=4)
graf1Ly<-ggplotly(graf1)%>% highlight(on = "plotly_hover", off = "plotly_deselect")
#it works!!
#**that NOT WORK in this way**, as its an object of class "c('SharedData', 'R6')"
df3<-df2Linked %>% group_by(year) %>% summarise(max=max(value),mean=mean(value),min=min(value))
graf2<-ggplot(df3)+geom_segment(aes(x=year,xend=year,y=min,yend=max,color=factor(year),group=year),size=10)+geom_point(aes(year,mean),size=2)
graf2Ly<-ggplotly(graf2)%>% highlight(on = "plotly_hover", off = "plotly_deselect")
subplot(graf1Ly,graf2Ly,nrows=2)
How has to be done it?
thanks
My suggestion is to use ggplotly() in each plot and than use subplot() from plotly
This isn't the pretty plot ever, but I think that it will help you:
graf1<-ggplot(df2)+
geom_line(aes(date,value,color=factor(year),group=year),size=4) +
labs(color='Year')
graf2<-ggplot(df3)+
geom_segment(aes(x=year,xend=year,y=min,yend=max,color=factor(year),group=year),size=10)+
geom_point(aes(year,mean),size=2) +
labs(color='Year')
subplot(ggplotly(graf1),ggplotly(graf2), nrows = 2)
The output:
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.
I want to use ggvis for data exploration (because I am familiar with ggplot2), and it would be of great help, due to many groups in my data sets, to be able to select and unselect groups to make different specific (data) comparisons.
set.seed(10)
dat <- data.frame(x=c(1:3,1:3),y=rnorm(6),groups=factor(rep(1:2,each=3)))
library(ggvis)
dat %>% ggvis(~x, ~y) %>% layer_points(fill=~groups)
# i know this example does not work - but is that possible somehow?
dat %>% ggvis(~x, ~y) %>% layer_points(fill=input_checkbox(~groups))
What I want at the end, is a graphic with which I can select a subset of groups by using radio buttons (for example).
Is there any way to do that?
Thank you!
From the documentation
Limitations
Currently, interactive inputs can only be used in two places:
as arguments to transforms: layer_smooths(span = input_slider(0, 1))
as properties: props(size = input_slider(10, 1000))
This means that interactive inputs can only modify the data, not the
underlying plot specification. In other words, with only basic
interactivity there’s no way to add or remove layers, or switch
between different datasets. This is a reasonable limitation because if
you’re doing exploration you can always create a new ggvis with R
code, or if you’re polishing a plot for presentation, you can embed it
in a Shiny app and gain full control over the plot.
For simple data exploration, one idea could be to use filter():
set.seed(10)
dat <- data.frame(x = c(1:5,1:5,1:5),
y = rnorm(15), groups = factor(rep(1:5,each=3)))
Note: I edited your initial dataset to illustrate the concept with more groups
library(dplyr)
library(ggvis)
dat %>% ggvis(~x, ~y) %>% layer_points(fill = ~groups)
You could pass the arguments (either manually directly in your R code or with your radio buttons in a Shiny app) to filter() to isolate specific groups:
dat %>%
filter(groups == 1 | groups == 3) %>%
ggvis(~x, ~y) %>% layer_points(fill = ~groups)
I have been fiddling around with ggvis and ran into this problem that I cannot use hexadecimal values for colours like regular R plots. Is this normal behaviour for ggvis or am I missing something?
library(ggvis)
# create data frame
df <- data.frame(var1=1:10,var2=5:14,var3=factor(c(rep("A",5),rep("B",5))))
# code without custom colours
df %>%
ggvis(x = ~var1, y = ~var2,fill = ~var3) %>%
layer_points(size := 30,fillOpacity := 0.5)
#code with custom colours as text
df %>%
ggvis(x = ~var1, y = ~var2,fill = ~var3) %>%
layer_points(size := 30,fillOpacity := 0.5) %>%
scale_nominal("fill",range=c("red","green"))
# code with custom colours as hexadecimal values
df %>%
ggvis(x = ~var1, y = ~var2,fill = ~var3) %>%
layer_points(size := 30,fillOpacity := 0.5) %>%
scale_nominal("fill",range=c("#0000FFFF","#FF3300FF"))
The 8-character codes you're using include 2 extra characters at the end, which, as you mentioned, control transparency. While these may be recognized in base R, ggvis is expecting a traditional hex code, i.e. one with 6 characters. To get the hex codes you need, simply omit the last 2 characters of your current color codes. Transparency is controlled separately through parameters passed to the ggvis family of functions.
Trying to replicate the ggplot function position="fill" in ggvis. I use this handy function all the time in the presentation of results. Reproducible example successfully performed in ggplot2 + the ggvis code. Can it be done using the scale_numeric function?
library(ggplot2)
p <- ggplot(mtcars, aes(x=factor(cyl), fill=factor(vs)))
p+geom_bar()
p+geom_bar(position="fill")
library(ggvis)
q <- mtcars %>%
ggvis(~factor(cyl), fill = ~factor(vs))%>%
layer_bars()
# Something like this?
q %>% scale_numeric("y", domain = c(0,1))
I think that to do this sort of thing with ggvis you have to do the heavy data reshaping lifting before sending it to ggvis. ggplot2's geom_bar handily does a lot of calculations (counting things up, weighting them, etc) for you that you need to do explicitly yourself in ggvis. So try something like the below (there may be more elegant ways):
mtcars %>%
mutate(cyl=factor(cyl), vs=as.factor(vs)) %>%
group_by(cyl, vs) %>%
summarise(count=length(mpg)) %>%
group_by(cyl) %>%
mutate(proportion = count / sum(count)) %>%
ggvis(x= ~cyl, y = ~proportion, fill = ~vs) %>%
layer_bars()