Why does ggplotly break when ggtern is loaded? - r

I was hoping to use plotly::ggplotly() to plot a graph produced with ggtern() with a tooltip feature. But loading the package ggtern caused ggplotly to throw the following error:
Error in inherits(theme[[element]], ggplot_global$element_tree[[element]]$class) :
'what' must be a character vector
What's more, this error appears for all graphs, not just those produced by ggtern.
Here is an example.
library(ggplot2)
# This works
gg.mtcars <- ggplot(mtcars, aes(hp, mpg)) +
geom_point()
plotly::ggplotly(gg.mtcars)
library(ggtern)
data("Feldspar")
gg.feldspar <- ggtern(data = Feldspar, aes(x = Ab, y = An, z = Or)) +
geom_point()
# This throws an error
plotly::ggplotly(gg.feldspar)
# And now this throws an error too
plotly::ggplotly(gg.mtcars)

Related

ggpubr ,ggpp, ggformula functions not working with ggplotly

I am using a few functions from ggpubr and ggpp to draw my plots.
Specifically, i am using the functions: geom_quadrant_lines(), stat_quadrant_lines(), geom_lm, stat_regline_equation in my plot.
However, when i convert my ggplot2 object into a plotly object using ggplotly(), the above dont seem to be working.
Is there any workaround? Adding the geoms to the plotly object also dont seem to work
Example Code and Errors Below:
library(ggplot2)
library(plotly)
library(ggpubr)
library(ggpp)
library(ggformula)
set.seed(1234)
data <- data.frame(x = -5:4 + runif(10,-1,1), y = seq(-15,12,3)-runif(10,-1,1)*2)
head(data)
g <- ggplot(data = data, aes(x=x, y=y)) +geom_point() +
stat_mean(color = "blue") +
geom_quadrant_lines()+
stat_quadrant_counts()+
stat_regline_equation( formula = y~x, aes(label = paste( ..eq.label.., ..adj.rr.label.., sep="~~")),output.type="expression", label.y.npc = 0.8, label.x.npc = 0.0, colour="black", size = 2.5) +
labs(title= "Example Plot") + #change the number of days here
geom_lm(interval = "prediction", level = 0.95)
g
p <- ggplotly(g)
p
p %>% geom_lm(mapping = aes(x=x, y=y), data = data, interval = "prediction", level = 0.95)
The ggplot2 output is
Once converted into plotly object using ggplotly, it becomes
I also get the below warning messages
> p <- ggplotly(g)
Warning messages:
1: In geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]) :
geom_GeomQuadrantLines() has yet to be implemented in plotly.
If you'd like to see this geom implemented,
Please open an issue with your example code at
https://github.com/ropensci/plotly/issues
2: In geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]) :
geom_GeomTextNpc() has yet to be implemented in plotly.
If you'd like to see this geom implemented,
Please open an issue with your example code at
https://github.com/ropensci/plotly/issues
3: In geom2trace.default(dots[[1L]][[1L]], dots[[2L]][[1L]], dots[[3L]][[1L]]) :
geom_GeomLm() has yet to be implemented in plotly.
If you'd like to see this geom implemented,
Please open an issue with your example code at
https://github.com/ropensci/plotly/issues

Error: geom_point requires the following missing aesthetics: x and y

If I use the following commands:
library(ggplot2)
p <- ggplot(mtcars, aes(wt, mpg))
p + geom_point()
all works fine.
If I run the following commands:
library(ggplot2)
library(ggtern)
p <- ggplot(mtcars, aes(wt, mpg))
p + geom_point()
I receive this error message:
Error: geom_point requires the following missing aesthetics: x and y
ggtern has a ggplot() function as well, so the duplicate name is messing it up. Best option is to load the packages in the opposite order (the last package loaded always wins when there are duplicate names), or try the following:
library(ggplot2)
library(ggtern)
p <- ggplot2::ggplot(mtcars, aes(wt, mpg))
p + ggplot2::geom_point()
I have restarted R and reloaded the packages many time, but the error remain. I work with a MacOS Big Sur 10.16, with R version 4.0.5 (2021-03-31), ggtern_3.3.0 and ggplot2_3.3.5.9000 –

ggplot2 - change line width in function graph

Say I have function like:
quad <- function(x)
{
return (x^2)
}
That I plot using ggplot:
plot <- ggplot(data.frame(x=c(0,4)), aes(x = x)) +
stat_function(fun = quad)
So far, so good, but the line is really thin. I thus add some specific geometry to the line:
plot + geom_line(size=2)
But it returns this error:
Error: geom_line requires the following missing aesthetics: y
How can I manipulate line geometry in this type of graphs?
After playing around a while I found out that an argument named size can be passed into stat_function. It has the same effect as gem_line:
plot <- ggplot(data.frame(x=c(0,4)), aes(x = x)) +
stat_function(fun = quad, size=1.5)

Overlaying exponential density over histogram of data

I have data that I made a histogram for (ur_memr_t$up...). I then used fitdistr to fit an exponential dist to the data. I captured the parameters for the fitted distribution and generated some random variates. I then made a density curve for the exp random variates. I want to place the density over the histogram. The following code throws this error
exp_data <- data.frame( x = rexp(3000, rate = 0.0144896182))
ggplot(data = ur_memr_t, aes(ur_memr_t$updated_days_to_next_ur)) +
geom_histogram() + ggplot(exp_data, aes(x)) + geom_density()
Error in p + o : non-numeric argument to binary operator
In addition: Warning message:
Incompatible methods ("+.gg", "Ops.data.frame") for "+"
If I run
ggplot(data = ur_memr_t, aes(ur_memr_t$updated_days_to_next_ur)) +
geom_histogram()
and
ggplot(exp_data, aes(x)) + geom_density()
seperately, they produce correct plots. Why will they not work together and plot one on top of the other?
I think it should work but you can only have one ggplot statement. Try something like this:
g = ggplot(data = ur_memr_t, aes(updated_days_to_next_ur))
g = g + geom_histogram(aes(updated_days_to_next_ur))
g = g + geom_density(data = exp_data, aes(x))
Hope it helps

How to capture ggplot2 errors?

I'm generating pdf reports using ggplot2. Code looks something like this
pdf()
for (){
p <- ggplot(..)
print(p)
}
dev.off()
Sometimes because of the data quality ggplot fails to generate the plot. There could be multiple reasons, and we don't want to check all possible combinations for data failing. We simply want to check if ggplot fails - and continue. This is what I came up with - this works, but there are some issues.
library(ggplot2)
p <- ggplot(mtcars, aes(wt, mpg)) +
geom_point()
p.bad <- ggplot(mtcars, aes(wt, as.character(mpg))) +
geom_point() +
scale_y_continuous()
pdf()
a <- try(print(p), silent = TRUE) # double printing
if (class(a)!='try-error'){
print(p)
}
b <- try(print(p.bad), silent = TRUE)
if (class(b)!='try-error'){
print(p.bad)
}
dev.off()
try(print) - generates a chart if there is no error. Is there a way of preventing it? This will probably the best solution. If we do the following - there is no double printing, but second try(print) generates blank page.
pdf()
a <- try(print(p), silent = TRUE)
b <- try(print(p.bad), silent = TRUE)
dev.off()
Is there another way of finding out if ggplot will generate an error?
I suggest to use ggsave:
ttt <- function() {
require(ggplot2)
p.bad <- ggplot(mtcars, aes(wt, as.character(mpg))) +
geom_point() +
scale_y_continuous()
a <- try(ggsave("test.pdf",p.bad))
return("test")
}
ttt()
# Saving 12.9 x 9.58 in image
# Error : Discrete value supplied to continuous scale
# [1] "test"

Resources