I'm trying to get a plot_ly (in R) faceted histogram plot to look like a ggplot2 plot, using facets.
I can see this question How to facet a plot_ly() chart?, which allows me to make a faceted histogram plot, but although I can fix the chosen bins, I can't fix the x axis title to be consistent, nor the range of the x axis, nor can I choose different colour for the individual histogram facets.
The following works as a minimal example:
library(plotly)
library(dplyr)
x <- data.frame(Ancestry = as.factor(sample(1:7,200, replace=T)), Est.Age = rnorm(200, mean=50, sd=20))
x %>% group_by(Ancestry) %>%
group_map (~ plot_ly(data = ., x = ~Est.Age, color = ~Ancestry,
type = "histogram", nbinsx = 18, bingroup = 1), .keep = TRUE) %>%
subplot(nrow=3, shareX=TRUE) %>% layout(xaxis = list(title = "Age"))
This code snippet produces the following plot (or similar, depending on the random number):
What I would like to see is a consistent x-axis across all plots (for comparison purposes), and the same x-axis title ("Age" in this case). I would also like to change the colour of the individual plots in the facets to be consistent with other plots I'm generating on the same dataset, which aren't faceted. How can I do this with plot_ly in R?
EDIT: I should say that I want the facets based on a factor in my dataframe, and I want the colours to be based on a list of colours in the same order as the factors in the dataframe.
Here is one possible way using ggplotly:
p <-ggplot(x, aes(x = Est.Age, fill=Ancestry))+
geom_histogram(bins = 10)+
facet_wrap(.~Ancestry)
ggplotly(
p = ggplot2::last_plot()
)
Related
Im trying to replicate a barplot (See picture below) in a Shiny app using Plotly in R.
The x-axis has tissue values, while each bar on the x-axis is split/stacked based on tissue details.
When I try to replicate the above graph, For some tissue values, I am unable to discretely differentiate between tissue details using the predefined plotly color scales (See 'Brain' and 'heart' below), The bars basically have variations of the same color family, making them hard to interpret.
Is it possible somehow to produce a graph with colors like the one I want to replicate, in plotly R?
Dynamically? As the tissue details for a tissue could change based on shiny select input selections.
This is my plotly function:
plot_ly(data = tissue_dt, y=~counts, x=tissue, type='bar', name=~tissue_detail, color=~tissue_detail, colors = "Paired") %>% layout(barmode ="stack")
Apart from this I have also tried "Set3" and all other plotly discrete colorscales, but to no luck.
The data being used for both the desired plot and the shiny plot, is the same
Note that the original plot uses a discrete color for each tissue/detail.
The best option, if the list of the tissue_detail is fixed is to use a manual palette like:
my.pal = {
"Adipose-subcutaneous" = "#a10335", #Or whatever color you want
"Adipose-visceral" = "#43a332",
"AdrenalGland" = "green2",
# AND the remaining categories. The labels should match those in tissue_detail
}
And the just use that palette in your plot
plot_ly(data = tissue_dt, y=~counts, x=tissue, type='bar', name=~tissue_detail, color=~tissue_detail, colors = my.pal) %>% layout(barmode ="stack")
This have an additional advantage if you use these data partially in other plots. Thus you can keep the assignation of colors to each tissue_detail even if there is some missing category in any of those plots.
With so many (sub) categories it will be rather difficult to define a meaningful discrete palette. However, with plotly's hover capabilities and by adding a (white) line around the bars, you should get a farily decent graph:
library(dplyr)
library(tibble)
library(plotly)
library(RColorBrewer)
tissues <- tibble(tissue = LETTERS)
set.seed(18012023)
tissue_dt <- tissues %>%
slice(rep(sample(26, 8), sample(14, 8, TRUE))) %>%
mutate(tissue_detail = paste(tissue, sample(letters, n(), TRUE))) %>%
right_join(tissues, "tissue") %>%
mutate(tissue_detail = coalesce(tissue_detail, tissue),
counts = rpois(n(), 200)) %>%
arrange(tissue)
plot_ly(data = tissue_dt, y = ~counts, x = ~ tissue,
type = "bar",
name = ~tissue_detail,
marker = list(line = list(color = "white",
width = 1.5)),
color = ~tissue_detail,
colors = ~ tissue_detail %>%
as.factor() %>%
nlevels() %>%
colorRampPalette(brewer.pal(9, "Set1"))(.)) %>%
layout(barmode ="stack")
I am trying to create a graph similar to the one in this picture.
You can see that they have flipped the direction of the blue bars even though they have positive x values. Right now, I am able to reproduce that bar graph but with the bars in the same direction. Is it possible to create this same type of graph in ggplot with the flipped bars and positive x values?
Here is a tidyverse solution
Libraries
library(tidyverse)
Data
df <-
tibble(
y = letters[1:15],
p = runif(15,5,100),
g = as.factor(rep(0:1,c(5,10)))
)
Code
df %>%
#Create auxiliary variable, where for a determined group the percentage become negative
mutate(
p2 = if_else(g == 0, -p,p),
y = fct_reorder(y,p2)
) %>%
ggplot(aes(p2,y, fill = g))+
geom_col()+
scale_x_continuous(
breaks = seq(-100,100,10),
#Make the labels positive
labels = seq(-100,100,10) %>% abs()
)
Output
I like the look that the density plot of the ggplot view (Below). I wanna know how make a similar graph using a set of data interpoled (Data: https://www.dropbox.com/s/z8jbz10nnydsqw5/data.txt?dl=0). In other words, i wanna a graph with discrete contour and shaded colors.
I will appreciate your help
For example:
The same plot is possible make with lattice package:
library(ggplot2)
library(lattice)
library(latticeExtra)
data=read.table("data.txt",header = T,sep = ";")
#discrete field
levelplot(var~long+lat,data = data,contour=T)
But, in ggplot i get this result when i apply the density plot:
ggplot(data,aes(x=long,y=lat))+geom_density2d(aes(fill=var))+theme_bw()
I don't wanna make a density plot. I just wanna make a plot that look like the density plot in figure 1.
With ggplot I believe you require something like ggplot(dat, aes(long, lat, fill = var)) + geom_raster() and not the geom_density2d function. The default fill function is continuous as shown below. Others can point you to the functions to use discrete colors.
For lattice, you have to provide the colors and the breakpoints to the levelplot function and to the colorkey argument list and to the labels argument list within the colorkey argument. It's not so obvious...but here is an example.
# dat <- read.delim(f, sep = ";")
myCol <- brewer.pal(11, "RdYlBu")[c(6,8:11)]
breaks <- seq(min(dat$var), max(dat$var), len = 6)
levelplot(var ~ long + lat, data = dat,
at = breaks,
col.regions = myCol,
colorkey = list(col = myCol, at = breaks,
labels = list(at = breaks, labels = round(breaks))
)
)
I'm trying to create a forest plot with R plotly where I want to color code the effect sizes (points) and their error bars by their corresponding p-values.
Here are toy data:
set.seed(1)
factors <- paste0(1:25,":age")
effect.sizes <- rnorm(25,0,1)
effect.errors <- abs(rnorm(25,0,1))
p.values <- runif(25,0,1)
Here's what I'm trying:
library(dplyr)
plotly::plot_ly(type='scatter',mode="markers",y=~factors,x=~effect.sizes,color=~p.values,colors=grDevices::colorRamp(c("darkred","gray"))) %>%
plotly::add_trace(error_x=list(array=effect.errors),marker=list(color=~p.values,colors=grDevices::colorRamp(c("darkred","gray")))) %>%
plotly::colorbar(limits=c(0,1),len=0.4,title="P-Value") %>%
plotly::layout(xaxis=list(title="Effect Size",zeroline=T,showticklabels=T),yaxis=list(title="Factor",zeroline=F,showticklabels=T))
which gives me:
Which is pretty close to what I want except for:
I'd like the error bars to be colored similar to the effect sizes (by the corresponding p-values).
Remove the two trace legends below the colorbar
Have the order of the labels on the y-axis be that of factors
Any idea?
Okay it took me a while to warm up my plotly skills. Since your first point was the most difficult, I will go reversely through your points.
That can be achied by manipulating the layout using categoryorder
and categoryarray in the yaxis-list (cf. motos answer here)
Set showlegend=FALSE
That was tricky. I had to move your second line (the error bars) in the first. Added a color vector to it. Put it in the plot_ly-function. Used split to allow the correct coloring by group. Added the color for the points in a marker-list. In additon I converted the p.values via the colorRamp to hex-because every simpler solution didn't work for me.
Looks like this:
The code (the colorbar created some issues):
### Set category order
yform <- list(categoryorder = "array",
categoryarray = rev(factors),
title="Factor",zeroline=F,showticklabels=T)
### set the color scale and convert it to hex
library(grDevices)
mycramp<-colorRamp(c("darkred","gray"))
mycolors<-rgb(mycramp(p.values),maxColorValue = 255)
### plot without the adjusted colorbar
library(plotly)
### Without colorbar adjustment
plot_ly(type='scatter',mode="markers",y=~factors,x=~effect.sizes,
color=~p.values,colors=grDevices::colorRamp(c("darkred","gray")),
error_x=list(array=effect.errors,color=mycolors),split=factors,showlegend=FALSE,marker=list(color=mycolors)) %>%
layout(xaxis=list(title="Effect Size",zeroline=T,showticklabels=T),yaxis=yform)
### The colorbar-adjustment kicks out the original colors of the scatter points. Either you plot them over
plot_ly(type='scatter',mode="markers",y=~factors,x=~effect.sizes,
color=~p.values,colors=grDevices::colorRamp(c("darkred","gray")),
error_x=list(array=effect.errors,color=mycolors),split=factors,showlegend=FALSE,marker=list(color=mycolors)) %>%
layout(xaxis=list(title="Effect Size",zeroline=T,showticklabels=T),yaxis=yform) %>%
colorbar(limits=c(0,1),len=0.4,title="P-Value",inherit=FALSE) %>%
add_trace(type='scatter',mode="markers",y=~factors,x=~effect.sizes,
showlegend=FALSE,marker=list(color=mycolors),inherit=FALSE) %>%
layout(xaxis=list(title="Effect Size",zeroline=T,showticklabels=T),yaxis=yform)
### or you try to set the colorbar before the plot. This results in some warnings
plot_ly() %>%
colorbar(limits=c(0,1),len=0.4,title="P-Value",inherit=FALSE) %>%
add_trace(type='scatter',mode="markers",y=~factors,x=~effect.sizes,
color=~p.values,colors=grDevices::colorRamp(c("darkred","gray")),
error_x=list(array=effect.errors,color=mycolors),split=factors,showlegend=FALSE,marker=list(color=mycolors)) %>%
layout(xaxis=list(title="Effect Size",zeroline=T,showticklabels=T),yaxis=yform)
Just odd that this first point was so difficult to solve and results in such a big code bracket, because normally plotly supports that pipe logic quite well and you get a very readable code with all the add-functions.
I expected e.g., some add_errorbar-function, but apparently you have to add the errorbars in the plot_ly-function and the color-vector for the errors only works if you use the split-function. If someone would like to comment or post an alternative answer with more readable code on this, that would be interesting.
Here is an idea by constructing first a ggplot2 graph and using ggplotly:
create a data frame :
df <- data.frame(factors = factor(factors, levels = factors), #note the order of the levels which determines the order of the y axes
effect.sizes = effect.sizes,
effect.errors = effect.errors,
p.values = p.values)
create the ggplot graph:
library(ggplot2)
library(plotly)
ggplot(df)+
geom_vline(xintercept = 0, color = "grey50") +
geom_point(aes(y = factors,
x = effect.sizes,
color = p.values)) +
geom_errorbarh(aes(y = factors,
xmin = effect.sizes - effect.errors,
xmax = effect.sizes + effect.errors,
x = effect.sizes,
color = p.values)) +
scale_color_continuous(low = "darkred", high = "gray")+
theme_bw() +
xlab("Effect Sizes")+
ylab("Factors") +
theme(panel.border = element_blank(),
plot.margin = margin(1, 1, 1, 1, "cm")) -> p1
ggplotly(p1)
data:
set.seed(1)
factors <- paste0(1:25,":age")
effect.sizes <- rnorm(25,0,1)
effect.errors <- abs(rnorm(25,0,1))
p.values <- runif(25,0,1)
I am using ggplotly object to visualize a scatterplot in a shiny dashboard. I have a plot colored using the values of a column. However, when I want to look at a certain part of the plot, I zoom in to know more about the points. Then the legend labels should adjust according to the points present in the visible window or selected/chosen region.
For example, I have a scatterplot below with full data and the cut column has five different values.
library(plotly)
set.seed(100)
d <- diamonds[sample(nrow(diamonds), 1000), ]
p <- ggplot(data = d, aes(x = carat, y = price, color = cut)) + geom_point()
ggplotly(p)
The output:
When I select a window of the plot, there are no points related to Fair or Good in the above plot. How to avoid them in the legend labels? How to adjust/update the labels to the selected region(example, as shown below)? Should this handled using shiny reactive features?