daattali / ggextra Goto Github PK
View Code? Open in Web Editor NEW📊 Add marginal histograms to ggplot2, and more ggplot2 enhancements
Home Page: http://daattali.com/shiny/ggExtra-ggMarginal-demo/
License: Other
📊 Add marginal histograms to ggplot2, and more ggplot2 enhancements
Home Page: http://daattali.com/shiny/ggExtra-ggMarginal-demo/
License: Other
As reported by a user in a private email, the first and last bins seem to be cut off. I'm suspecting it's because the first bin's left edge is actually outside of the range of the main plot. For example, if the main scatterplot begins at x = 10, then maybe the first bin is centered at x = 10, but its left edge is at x = 9, which is not within the range.
I have a geom_boxplot() + coord_flip(). Adding a marginal histogram to the y axis places it on the true x axis. Trying to add it to the x axis throws an error.
Hi,
I couldn't find the way not to plot the outer frame when combining graphs through ggplot2 + ggExtra + cowplot. I am not sure where I have to tell R, but suspect the issue to lie in ggExtra. Here is an example:
require(ggplot2)
require(cowplot)
require(ggExtra)
A <- ggplot(mpg, aes(x = cty, y = hwy, colour = factor(cyl))) + geom_point(size = 2.5)
B <- ggExtra::ggMarginal(A,type = 'histogram', margins = 'x', size = 9)
combo <- plot_grid(B,B,labels=c("A","B"))
plot(combo) # looks fine
plot_grid(B,combo,ncol=1,rel_heights = c(2,3))
The question is also posted on Stackoverflow, here.
Thanks for any help!
Minimal example:
library("ggExtra")
# Create some data
set.seed(1234)
x <- c(rnorm(500, mean = -1), rnorm(500, mean = 1.5))
y <- c(rnorm(500, mean = 1), rnorm(500, mean = 1.7))
col <- c(rnorm(500, mean = 1), rnorm(500, mean = 1.3))
df3 <- data.frame(x, y, col)
# Scatter plot of x and y variables and color by groups
sp2 <- ggplot(df3,aes(x, y, color=col)) + geom_point()
ggMarginal(sp2 + theme_gray(), type="histogram")
The legend and the y-axis histogram should be switched.
There was a blog post showing how to do many Tufte-style plots in R. The author included ggMarginal
but noted that it cannot be used to make dotplots eg
I suppose it could be a nice extra feature to support those kind of plots as well, even though they're very very similar to histograms. I looked into it very briefly and unfortunately the ggplot2::geom_dotplot()
doesn't seem to work because when there are many observations the dots go off the screen. There might be a way to somehow dynamically decide how big to make the dots. There can also be other solutions (perhaps useful resource: http://lenkiefer.com/2016/04/06/dot-plots-and-distributions)
If anybody wants to tackle this, feel free to make a PR!
Occasionally, I like to have both axes of a scatter have the same range or limits (in the original plot below I set the limits to c(-20,30)). However, to demonstrate the issue, I changed the y-axis limits using scale_y_continuous(limits = c(-40,30)) while having scale_x_continuous(limits = c(-20,30)).
The actual range of the data in the x-axis is: -17.49, 28.56 and on the y-axis is: -9.63, 17.58
I think the location of histograms should adjust and shift when the axes limits are shifted.
as suggested by a reddit user
With the upgrade of shiny says "No layers in plot" which should be the graph:
library(ggExtra)
data(airquality)
airquality$Date <- with(airquality, as.Date(sprintf('1973-%02d-%02d', Month, Day)))
p <- ggplot(airquality, aes(Date, Temp)) + geom_point()
print(ggMarginal(data = airquality, x = 'Date', y = 'Temp')) # works
print(ggMarginal(p, airquality, 'Date')) # doesn’t
the second one throws:
Error: Invalid input: date_trans works with objects of class Date only
Traceback:
1. print(ggMarginal(p, airquality, "Date"))
2. ggMarginal(p, airquality, "Date")
3. ggplot2::ggplot_build(top)
4. lapply(data, scales_transform_df, scales = scales)
5. FUN(X[[i]], ...)
6. unlist(lapply(scales$scales, function(s) s$transform_df(df = df)),
. recursive = FALSE)
7. lapply(scales$scales, function(s) s$transform_df(df = df))
8. FUN(X[[i]], ...)
9. s$transform_df(df = df)
10. f(..., self = self)
11. lapply(df[aesthetics], self$transform)
12. FUN(X[[i]], ...)
13. f(..., self = self)
14. self$trans$transform(x)
15. stop("Invalid input: date_trans works with objects of class Date only",
. call. = FALSE)
At some point in the past year, the bottom margin of the x axis label has disappeared. The label is stuck to the bottom of the image without any space, and any letters that go lower the the standard line (such as "g" "j" "p" "q" "y") are cut off.
I'm not sure if this is because of newer ggplot version, or because of the refactoring from #26
Hi. I am having a lot of trouble installing gridExtra. First, grid doesn't install under the current version of R and then when I try running running the package I get "Error: gridExtra
package is required for this function to work. Please install it." even though the package is installed. Help?
I can't include gridExtra in my package because of a bug that's fixed in their GitHub version but not on CRAN. Get them to submit the fix to CRAN.
Right now ggMarginal
only carries the color and font face of the scatter plot's title through to the final plot. The text grob that we use for a title in the final plot is created here:
title <- grid::textGrob(
pb$plot$labels$title,
gp = grid::gpar(col = pb$plot$theme$plot.title$colour,
fontsize = 16, fontface = pb$plot$theme$plot.title$face)
)
It's easy to pull out the ggplot2 titleGrob
that contains all of the theme elements desired by the user, and drop that grob in instead of using grid::textGrob
. I will include this in the next PR.
Hi there -
Two initial questions I have come across while refactoring:
# after ggplot2 v1.0.1, layers became strict about parameters
if (type == "density") {
extraParams[['fill']] <- NULL
}
I'm getting the behavior that I would want (a warning from ggplot: "Warning: Ignoring unknown parameters: fill") when I drop those lines from ggMarginal and I run this code:
p <- ggplot2::ggplot(mtcars, ggplot2::aes(wt, mpg)) + ggplot2::geom_point()
ggExtra::ggMarginal(p, type = "density", fill = "black")
I also don't understand why this line would be needed for a density geom and not boxplot/histogram but that's probably just my ignorance.
if (missing(p)) {
if (missing(data) || missing(x) || missing(y)) {
stop("`data`, `x`, and `y` must be provided if `p` is not provided",
call. = FALSE)
}
p <- ggplot2::ggplot(data, ggplot2::aes_string(x, y)) + ggplot2::geom_point()
x <- as.symbol(x)
y <- as.symbol(y)
} else {
if (missing(data)) {
if (methods::is(p$data, "waiver")) {
stop("`data` must be provided if it is not part of the main ggplot object",
call. = FALSE)
}
data <- p$data
}
if (length(p$mapping) == 0) p$mapping <- p$layers[[1]]$mapping
if (margins != "y" && missing(x)) {
if (is.null(p$mapping$x)) {
stop("`x` must be provided if it is not an aesthetic of the main ggplot object",
call. = FALSE)
}
x <- p$mapping$x
}
if (margins != "x" && missing(y)) {
if (is.null(p$mapping$y)) {
stop("`y` must be provided if it is not an aesthetic of the main ggplot object",
call. = FALSE)
}
y <- p$mapping$y
}
}
...We already make sure in the if
statement that the user provided data
, x
, and y
if they didn't provide p
. Under what circumstance could they pass this test and be thrown an error in the else
block? In other words, under what circumstances would the user supply a ggplot object p
but you still need them to supply x
, y
, or data
? It looks like it may be an assertion that you ggplot still keeps x
, y
, and data
where you think they will be in the plot object, but it's hard to tell if you're testing that or user params.
I love the package, can I suggest a new geom?
Or is there another ggplot extension where this would fit better?
a split violin plot. That is, two densities of groups with the backs to eachother. This stack overflow question has a custum function, but it might be something to add?
https://stackoverflow.com/questions/35717353/split-violin-plot-with-ggplot2
Great package, anyway I think it could be useful to have the possibility to show the axis of the density plot/histogram, in order to be able to compare distributions of subsets of data (see pict):
As you can see the maximum of each the density distribution is the same, therefore it's not possible to appreciate the differences in density value.
Thanks in advance.
Sebastiano
It will be nice to able to show geom_hex along with two densities on top and right since there are circumstances where scatterplot is too slow due to the huge number of events.
As suggested by @_zakahmad on twitter
ggMargin is great. But it changes bold main title to plain text, which is not desired.
p <- ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point() + theme_bw() +
labs(title="Main Title", y="MPG") +
theme(plot.title=element_text(face="bold", size=14),
axis.title.y=element_text(face="bold", size=14))
p's main title and y are bold.
ggMarginal(p, margins="y", size=4)
Now main title is changed to plain text. The y title font face is not affected. Can you maintain the font face of main title?
Now it only supports one panel, it will be useful to support multi-panel plots faceted by either facet_wrap
or facet_grid
NOTE: Problem only happens on smaller monitors.
My 2nd monitor, where I run R studio, is 14 inches diag.
(No problem on larger monitors)
Using your great mtcars ggExtra Margins example,
in the latest Rstudio / Linux.
From the Console panel,
this works ok:
library(ggplot2)
library(ggExtra)
myplot <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
But...using the Rstudio "addin"
from the Code panel,
shows:
http://imgur.com/epvDELb
See?
The bottom part of the plot is "cut-off" (below mpg=10)
...can not see the wt x-axis.
So yes, everybody with smaller monitors
may have that problem.
Q: (possible solution?)
Is there a way
to make the results Margins popup window,
"user-resizable"?.
I'm sure that if I could use the mouse
to "resize" that popup,
the hidden parts will re-appear OK,
even on smaller monitors.
btw:
There is lots of unused screen space
around that popup,
so allowing the user to mouse-resize it,
would certainly solve the problem! :-)
I keep getting this error, "Error: StatBin requires a continuous x variable the x variable is discrete. Perhaps you want stat="count"?" How do I solve this issue?
This isn't trivial because I don't know how to generalize looking for the current scale on a plot and using the same scale on another plot. I can manually check "is there a log x/y scale? if so, then add a log x/y scale to the margin plots" and repeat that for every common transformation. But not sure yet how to do it efficiently.
library(ggplot2)
library(ggExtra)
set.seed(123)
df <- data.frame(x = rlnorm(100), y = rlnorm(100))
p1 <- ggplot(df, aes(x, y)) + geom_point() + scale_x_log10() + scale_y_log10()
ggMarginal(p1, type = "histogram")
First, thank you very much for developing such a nice package!
I am having this error when running the function 'ggMarginal'
Error in data.frame(x = .Primitive("log10"), PANEL = c(1L, 1L, 1L, 1L, :
arguments imply differing number of rows
Any idea how to solve the problem?
Maybe this is related to the log10 in the formula in ggplot2.
The code used:
p1 <- ggplot(dat.crop, aes(y = log10(AGr), x = log10(herb + 1))) +
geom_point(size = 3, color = "tomato")+
geom_smooth(method = "lm")
ggMarginal(p1, type = "histogram")
Thanks in advance
Depending on the type of marginal plot, ggMarginal
will pass along one of these warnings:
type = histogram
- i.e., ggMarginal(data = mtcars, x = "mpg", y = "wt", type = "histogram")
`stat_bin()` using `bins = 30`.
Pick better value with
`binwidth`.
type = boxplot
- i.e., ggMarginal(data = mtcars, x = "mpg", y = "wt", type = "boxplot")
Warning messages:
1: Continuous x aesthetic -- did you forget aes(group=...)?
2: Continuous x aesthetic -- did you forget aes(group=...)?
3: Continuous x aesthetic -- did you forget aes(group=...)?
type = density
- i.e., ggMarginal(data = mtcars, x = "mpg", y = "wt", type = "density")
Warning: Ignoring unknown parameters: fill
Warning: Ignoring unknown parameters: fill
In my opinion we should only pass along the warning in case number 1 (i.e., the binwidth warning when type = histogram
). The other two warnings are not helpful and are the result of expected behavior. What do you think - should we suppress these warnings?
would you be interested in a contribution (pull request) of some horizontal variants of geoms such as linerange (useful when trying to use faceting and flipped coordinates together, which is not currently feasible in ggplot2)?
e.g. see:
ggplot2 is being updated again, and it looks like the internal changes in ggplot2 are completely breaking ggMarginal. Again. :(
I am trying to replicate the example:
library("ggplot2")
library("ggExtra")
set.seed(30)
df <- data.frame(x = rnorm(500, 50, 10), y = runif(500, 0, 50))
p <- ggplot(df, aes(x, y)) + geom_point()
ggMarginal(p)
Which results the following error:
Error: Don't know how to add o to a plot
In addition: Warning message:
In mean.default(getLimits(pbTop, "y")) :
argument is not numeric or logical: returning NA
Session info:
R version 3.3.2 (2016-10-31)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: macOS Sierra 10.12.3
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] ggExtra_0.6.1 ggplot2_2.2.1.9000
loaded via a namespace (and not attached):
[1] Rcpp_0.12.9 digest_0.6.12 assertthat_0.1 mime_0.5 grid_3.3.2
[6] plyr_1.8.4 R6_2.2.0 xtable_1.8-2 gtable_0.2.0 scales_0.4.1
[11] lazyeval_0.2.0 miniUI_0.1.1 labeling_0.3 tools_3.3.2 munsell_0.4.3
[16] shiny_1.0.0.9000 httpuv_1.3.3 colorspace_1.3-2 htmltools_0.3.5 tibble_1.2
as suggested by @baptiste
Hi,
I would like to add y-axis labels for the marginal plots. Is there a way to do it using ggMarginal command?
Thanks,
Lavanya
Hi Dean,
Thank you for your work in ggExtra package, which makes it really easy to add marginal plots to ggplots.
It would be highly appreciated, if one can add marginal plots for grouped data as illustrated here and here
Suggestion: Improve ggMarginal()
so that it reacts to the mapping
arguments.
sp <- ggplot(iris, aes(Sepal.Length, Sepal.Width))+
geom_point(aes(color = Species))
ggMarginal(sp, data = iris, mapping = aes(color = Species) )
Best regards,
Error: no layers in the plot
still occures when you have an old version of gridExtra (it does not work for me for version gridExtra_0.9.1) so you should ensure that user has at least version 2.0.0 of gridExtra. Can you fix this somehow or add it to the vignette/info/description?
It would add more convenience to an already convenient function. An idea:
rotateTextX <- function (angle = 90, hjust = angle/90, vjust = 0.5)
{
ggplot2::theme(
axis.text.x = ggplot2::element_text(angle = angle, hjust = hjust, vjust = vjust)
)
}
Is it possible to use your fantastic package to create a plot described in this question :)?
Dear @daattali,
I am using ggExtra on a shiny app. I dont know why, but today the rendered plot changed and the histogram is now a "rug" like plot. Any advise on that?
See below a small reproducible example.
library(ggplot2); library(ggExtra)
set.seed(30)
df1 <- data.frame(x = rnorm(500, 50, 10), y = runif(500, 0, 50))
(p1 <- ggplot(df1, aes(x, y)) + geom_point() + theme_bw())
ggMarginal(p1, type = "histogram")
#> Scale for 'x' is already present. Adding another scale for 'x', which
#> will replace the existing scale.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.