I am trying to make a stacked area chart in R exactly like this ggplot2 one (below) only using plotly.
Here is a link to my data.
To generate a plotly version of the above ggplot2 chart, I first have to add the values of each column in my dataframe, elw, on top of the values in the previous column like so. This is because plotly (as far as I'm aware) does not have the ability to automatically stack values in area charts.
With this new stacked data set, elw_stack, I use the following code to make my plotly chart:
el_plot2 = ggplot() +
geom_area(aes(elw_stack$year, elw_stack$x99999, fill = 'green')) +
geom_area(aes(elw_stack$year, elw_stack$x20000, fill = 'red')) +
geom_area(aes(elw_stack$year, elw_stack$x19000, fill = 'blue')) +
geom_area(aes(elw_stack$year, elw_stack$x12018, fill = 'purple')) +
geom_area(aes(elw_stack$year, elw_stack$x10006, fill = 'yellow'))
ggplotly(el_plot2)
That code generates this chart:
The issue is that the plotly labels refer to the cumulative elw_stack values. The green value pictured at year 1999 is actually ~3700 (i.e. 11,365 - 7957). But the description bar says the cumulative value of 11,365. Is there a way to fix this so that the labels aren't cumulative values?
I was having a similar problem and eventually decided not to use ggplotly, but instead i used the plot_ly function. Here is the code I used with your data:
elw <- read.csv("elw.csv")
elw_stack <- read.csv("elw_stack.csv")
plot <- plot_ly(data=elw_stack, x=year, y=x10006, fill="tonexty", mode="lines",
text=round(elw$x10006, 0), hoverinfo='x+text+name', name="x10006")
plot <- add_trace(plot, data=elw_stack, x=year, y=x12018, fill="tonexty", mode="lines",
text=round(elw$x12018,0), hoverinfo='x+text+name', name="x12018")
plot <- add_trace(plot, data=elw_stack, x=year, y=x19000, fill="tonexty", mode="lines",
text=round(elw$x19000,0), hoverinfo='x+text+name', name="x19000")
plot <- add_trace(plot, data=elw_stack, x=year, y=x20000, fill="tonexty", mode="lines",
text=round(elw$x20000,0), hoverinfo='x+text+name', name="x20000")
plot <- add_trace(plot, data=elw_stack, x=year, y=x99999, fill="tonexty", mode="lines",
text=round(elw$x99999,0), hoverinfo='x+text+name', name="x99999")
plot <- layout(plot, yaxis=list(title="Whatever title you wanna use"))
And this is how the final plot looks:
plotly image
What I can't get to work is to add the different traces using a for loop. I wanted to write a function that takes a data frame with an arbitrary number of columns as input and returns the stacked area plot, but for some reason the plot won't show all the traces (only first and last)
Hope it helps...
Related
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()
)
I am trying to generate density plot with two overlaid distributions using ggplot2. My data looks like:
diag_elements <- data.frame(x = c(diag(Am.dent), diag(Am.flint)),
group=rep(c("Dent", "Flint"), c(length(diag(Am.dent)), length(diag(Am.flint)))))
And my call to ggplot is:
ggplot(diag_elements) +
geom_density(aes(x=x, colour=group, fill=group), alpha=0.5) +
labs(x = "Diagonal elements of the matrix", y = "Density", fill = "Heterotic Group") +
theme(legend.position = c(0.85, .75))
However, instead of simply renaming the legend with the more complete name specified in fill, this generates a second legend:
Does anyone have any suggestions for getting this same graph, but without the improperly formatted legend?
Thanks!
The other option is guides which allows specific removal of certain legneds. You simply add to your ggplot
+guides(color=FALSE)
I'm trying to make a plot with five separate lines that represent different variables (i.e., columns). I've been trying to fix the legend and I can't get it right. The colors also seem to be incorrect, so I'm confused as to how to proceed. Data, code, and current plot are below:
test.dat <- data.frame(matrix(c(0,.072,.063,.062,.059,.055,1,.029,.035,.024,.036,.017),
nrow=2,byrow=T))
colnames(test.dat) <- c("X1","Y1","Y2","Y3","Y4","Y5")
test.plot <- ggplot(data=test.dat) +
geom_line(aes(x=X1, y=Y1, color="darkred")) +
geom_line(aes(x=X1, y=Y2, color="darkgreen")) +
geom_line(aes(x=X1, y=Y3, color="darkblue")) +
geom_line(aes(x=X1, y=Y4, color="darkorange")) +
geom_line(aes(x=X1, y=Y5, color="darkgoldenrod"))
I'm trying to make the variable names (i.e., Y1, Y2, etc.) the names for the lines on the legend as well as name the legend itself. I've googled around to figure out how to change the legend, but nothing I've tried changes the plot. I also need to fix the the axis labels and add a plot title.
I'm fairly new to ggplot, so a point in the right direction would be much appreciated. Please let me know if I can clarify anything.
It is easier if you change your data from wide to long, and then plot the lines. You are also defining the colors within the aes() parameter which does not change the color, but, in effect, creates a variable with that value.
You did not mention exactly what you want to do with your axis labels, but they can be edited using scale_x_continuous or scale_y_continuous
library(tidyverse)
test.dat <- data.frame(matrix(c(0,.072,.063,.062,.059,.055,1,.029,.035,.024,.036,.017),
nrow=2,byrow=T))
colnames(test.dat) <- c("X1","Y1","Y2","Y3","Y4","Y5")
test.dat %>%
gather(Y_var, value, -X1) %>%
ggplot(aes(x = X1, y = value, color = Y_var)) +
geom_line() +
scale_color_manual(
values = c("darkred","darkgreen","darkblue","darkorange",
"darkgoldenrod")
) +
labs(title = "Some plot title",
color = "Some legend title")
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?