R: adjusting legend labels to the selected (gg)plotly output - r

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?

Related

Format plot_ly faceted histogram chart

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()
)

Showing discrete variable in a single geom_sina/violin plot

I'm trying to create a plot with geom_sina and geom_violin where all data points are plotted together (as one violin shape) and are coloured by a factor.
However, when I specify ggplot(mtcars, aes(x = "", y = mpg, fill = am)), the plot is split according to the factor, which is what I'd like to avoid (plot 1). The closest I've come is treating the factor as a continuous variable (plot 2). But then the legend displays a "fill" bar and not the discrete factor levels I'd like.
So, if possible, I'd like the plot to stop splitting by colour when using a factor, or to overide the legend to discrete values if going with numerics.
Any help is much appreciated : )
plot 1
plot 2
Maybe this is what you are looking for. Using the group aesthetic you could overwrite the default grouping by fill or color or ...:
Note: As you want the points do be colored I switched to the color aesthetic.
library(ggplot2)
library(ggforce)
ggplot(mtcars, aes(x = "", y = mpg)) +
geom_violin() +
geom_sina(aes(color = factor(am), group = 1))

How do I add a separate legend for each variable in geom_tile?

I would like to have a separate scale bar for each variable.
I have measurements taken throughout the water column for which the means have been calculated into 50cm bins. I would like to use geom_tile to show the variation of each variable in each bin throughout the water column, so the plot has the variable (categorical) on the x-axis, the depth on the y-axis and a different colour scale for each variable representing the value. I am able to do this for one variable using
ggplot(data, aes(x=var, y=depth, fill=value, color=value)) +
geom_tile(size=0.6)+ theme_classic()+scale_y_continuous(limits = c(0,11), expand = c(0, 0))
But if I put all variables onto one plot, the legend is scaled to the min and max of all values so the variation between bins is lost.
To provide a reproducible example, I have used the mtcars, and I have included alpha = which, of course, doesn't help much because the scale of each variable is so different
data("mtcars")
# STACKS DATA
library(reshape2)
dat2b <- melt(mtcars, id.vars=1:2)
dat2b
ggplot(dat2b) +
geom_tile(aes(x=variable , y=cyl, fill=variable, alpha = value))
Which produces
Is there a way I can add a scale bar for each variable on the plot?
This question is similar to others (e.g. here and here), but they do not use a categorical variable on the x-axis, so I have not been able to modify them to produce the desired plot.
Here is a mock-up of the plot I have in mind using just four of the variables, except I would have all legends horizontal at the bottom of the plot using theme(legend.position="bottom")
Hope this helps:
The function myfun was originally posted by Duck here: R ggplot heatmap with multiple rows having separate legends on the same graph
library(purrr)
library(ggplot2)
library(patchwork)
data("mtcars")
# STACKS DATA
library(reshape2)
dat2b <- melt(mtcars, id.vars=1:2)
dat2b
#Split into list
List <- split(dat2b,dat2b$variable)
#Function for plots
myfun <- function(x)
{
G <- ggplot(x, aes(x=variable, y=cyl, fill = value)) +
geom_tile() +
theme(legend.direction = "vertical", legend.position="bottom")
return(G)
}
#Apply
List2 <- lapply(List,myfun)
#Plot
reduce(List2, `+`)+plot_annotation(title = 'My plot')
patchwork::wrap_plots(List2)

Plot must contain exactly one panel; marginal box plot on faceted scatterplot

I am very new to programming, but I managed to get around making faceted scatterplots and marginal box plots for scatter plots using advice in the link below: http://www.lreding.com/nonstandard_deviations/2017/08/19/cowmarg/
My question is how can I make marginal boxplots on my faceted scatterplot?
My code is:
CN<-read.csv("LfFlw.csv")
library(ggplot2)
Simple scatter plot:
ggplot(data=CN, aes(x=PlantOrder, y=CN, colour=Tissue))+geom_point()+facet_wrap(~Population, scales="free_x", nc=2)
Scatterplot black and white:
sc<-ggplot(data=CN, aes(x=PlantOrder, y=CN, shape=Tissue))+geom_point()+facet_wrap(~Population, scales="free_x", nc=2)
sc
Scatter plot with labelled axes:
sc_lab<-sc+labs(x="Individual plants (ordered)", y="Cyanide (ug g^-1 dw)")
sc_lab
Scatter plot with labelled axes and classic theme:
sc_lab_th<-sc_lab+theme_classic()
sc_lab_th
Scatter plot with labelled axes and classic theme with changed shapes:
s<-sc_lab_th+scale_shape_manual(values=c(8,2))
s
Boxplot with facet and white/grey:
y_box <- axis_canvas(s, axis = "y") + geom_boxplot(data = CN, outlier.shape = 1, aes(x = 0, y = CN, fill=Tissue)) +
facet_wrap(~Population, scales="free_x", nc=2)+scale_fill_manual(values=c("white", "grey"))
y_box
library(cowplot)
ggdraw(insert_yaxis_grob(s, y_box, position = "left"))
And here I end up with an error:
Error in get_panel(grob) : Plot must contain exactly one panel
The answer is: You can't. (At least not via the axis_canvas() / insert_yaxis_grob() route. The error message tells you exactly what's going on: The function insert_yaxis_grob() can only insert plots that consist of a single panel. You've made a faceted plot, which contains multiple panels.

plotly labels in R stacked area chart

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...

Resources