I am having some difficulty with the ggplot2 package and the gradient fill. For my data with low number of data points, its gradient and density intensity doesn't really match. Here is an example:
The code I am using is:
pt <- read.xlsx("plots.xlsx", sheetName = "PT1_TB varseq", stringsAsFactors=FALSE)
ggplot(pt, aes(x=pt$BAF, y=pt$LogR) ) +
stat_density_2d(aes(fill = ..density..), geom = "raster", contour = FALSE) +
scale_fill_distiller(palette= "Spectral", direction=-1) +
scale_y_continuous(name="LogR", limits = c(-0.8, 0.6), breaks = seq(-0.8, 0.6, 0.2)) +
scale_x_continuous(name="BAF", breaks = seq(0, 0.8, 0.2)) +
theme(
legend.position='none',
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
axis.line = element_line(colour = "black")
) +
geom_point(aes(shape = factor("cyl")), size = 1) + scale_shape(solid = FALSE)
I would like the gradient to change more abruptly, for example, I would like to see more seperation in colors between points at (0;0.2) and (0.25;-0.2). Furthermore the yellow color in the middle where no points are should be blue.
While I am at it, does anybody know how remove the white gap between the axes and the actual plot?
Thanks in advance :)
It would help if you could provide a reproducible example. However, to drive the point in the comment by #RichardTelford home, here's an example which leverages the manipulate package to interactively set the h bandwidth parameters, in addition to n -- the number of grid points.
library(ggplot2)
library(manipulate)
manipulate(
ggplot(faithful, aes(x = eruptions, y = waiting)) +
geom_point() +
xlim(0.5, 6) +
ylim(40, 110) +
stat_density_2d(geom = "raster", aes(fill = ..density..), contour = F,
h = c(x_bandwidth, y_bandwidth),
n = grid_points) +
scale_fill_distiller(palette = "Spectral", direction = -1),
x_bandwidth = slider(0.1, 20, 1, step = 0.1),
y_bandwidth = slider(0.1, 20, 1, step = 0.1),
grid_points = slider(1, 100, 16)
)
So our plain-vanilla (default) plot looks like this:
We can interactively change the parameters using the pop-up menu accessible from the gear icon:
Related
How do I get it so that it returns a box-plot without upper & lower whiskers? When I run this:
a <- ggplot(df1, aes(Name, Values)) +
geom_violin(width = 6, alpha = 0.5, trim = FALSE) +
geom_boxplot(width = 1, fill = "black", colour = "black", alpha = 0.5) +
geom_jitter(size = 1, alpha = 0.5) +
stat_summary(fun = mean, geom = "point", shape = 6, alpha = 0.5) +
theme(panel.grid.major.x = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor.x = element_blank(),
panel.grid.minor.y = element_blank()) +
ggtitle(label = "Title of Plot")
a
I get a boxplot without upper & lower whiskers. However when I run this:
ggplotly(a)
I get a boxplot with upper & lower whiskers. I require the plot to be interactive, but I want to remove the upper & lower whiskers. How would I do this?
Other than starting in Plotly or removing the whiskers in ggplot, you can change them by modifying the ggplotly object whiskerwidth for each type = "box" trace.
plt <- ggplotly(a) # create a ggplotly object
invisible(lapply(1:length(plt$x$data),
function(k) { # ensure it's a box trace
if(isTRUE(plt$x$data[[k]]$type == "box")) {
plt$x$data[[k]]$whiskerwidth <<- 0 # no width whiskers
}
}))
plt # check out the change
I am including marginal distribution plots on a scatterplot of a continuous and integer variable. However, in the integer variable maringal distribution plot (y-axis) there is this zig-zag pattern that shows up because the y-values are all integers. Is there any way to increase the "width" (not sure that's the right term) of the bins/values the function calculates the distribution density over?
The goal is to get rid of that zig-zag pattern that develops because the y-values are integers.
library(GlmSimulatoR)
library(ggplot2)
library(patchwork)
### Create right-skewed dataset that has one continous variable and one integer variable
set.seed(123)
df1 <- data.frame(matrix(ncol = 2, nrow = 1000))
x <- c("int","cont")
colnames(df1) <- x
df1$int <- round(rgamma(1000, shape = 1, scale = 1),0)
df1$cont <- round(rgamma(1000, shape = 1, scale = 1),1)
p1 <- ggplot(data = df1, aes(x = cont, y = int)) +
geom_point(shape = 21, size = 2, color = "black", fill = "black", stroke = 1, alpha = 0.4) +
xlab("Continuous Value") +
ylab("Integer Value") +
theme_bw() +
theme(panel.grid = element_blank(),
text = element_text(size = 16),
axis.text.x = element_text(size = 16, color = "black"),
axis.text.y = element_text(size = 16, color = "black"))
dens1 <- ggplot(df1, aes(x = cont)) +
geom_density(alpha = 0.4) +
theme_void() +
theme(legend.position = "none")
dens2 <- ggplot(df1, aes(x = int)) +
geom_density(alpha = 0.4) +
theme_void() +
theme(legend.position = "none") +
coord_flip()
dens1 + plot_spacer() + p1 + dens2 +
plot_layout(ncol = 2, nrow = 2, widths = c(6,1), heights = c(1,6))
From ?geom_density:
adjust: A multiplicate [sic] bandwidth adjustment. This makes it possible
to adjust the bandwidth while still using the a bandwidth
estimator. For example, ‘adjust = 1/2’ means use half of the
default bandwidth.
So as a start try e.g. geom_density(..., adjust = 2) (bandwidth twice as wide as default) and go from there.
I want to show a tick mark for theta axis in the ggplot2 poar plot. However, both axis.ticks.y and axis.ticks.y in the theme() does not work for theta axis. Any help would be appreciated, thanks
library(ggplot2)
df <- data.frame(
start = c(0, 121, 241),
end = c(120, 240, 359),
group = letters[1:3]
)
# a example circular ring plot
base <- ggplot(df, aes(ymax = end, ymin = start,
xmin = 0.8, xmax = 1,
fill = group)) +
geom_rect() +
coord_polar(theta = "y") +
xlim(c(0, 1))
base
# the tick of y axis can be changed
base + theme(axis.ticks.y = element_blank(), axis.text.y = element_blank())
# set the tick of x axis not worked for the theta axis
base + theme(axis.ticks.x = element_line(color = "black", size = 2))
Thanks for #Vishal A., the answer from Controlling ticks and odd text in a pie chart generated from a factor variable in ggplot2 used the panel.grid.major.y. However, it will add the major grids rather than ticks like the following:
base + theme(panel.grid.major.y = element_line(colour = "black"))
Created on 2021-12-20 by the reprex package (v2.0.1)
I see two options. You can use the panel grids, but you need to hide them. The usefulness of this solution depends on your intended plot background. I've used white, but this can be customised, of course.
Second option is to fake the ticks with annotation, e.g., with the symbol "|".
Further smaller comments in the code below.
library(tidyverse)
df <- data.frame(
start = c(0, 121, 241),
end = c(120, 240, 359),
group = letters[1:3]
)
ggplot(df) +
## annotate with a rectangle, effectively covering your central hole
annotate(geom = "rect", xmin = 0, xmax = 1, ymin = min(df$start), ymax = max(df$end),
fill = "white") +
## move aes to the geom_layer
geom_rect(aes(ymax = end, ymin = start,
xmin = 0.8, xmax = 1,
fill = group)) +
coord_polar(theta = "y") +
xlim(c(0, 1)) +
theme(panel.grid.major.y = element_line(colour = "black"))
## Option 2 - fake the ticks
## the position along the theta axis is defined by y
## you need to change the angle of your fake ticks according to the angle.
df_annot <-
data.frame(y = seq(0,300,100), x = Inf, angle = 360-seq(0,300,100))
ggplot(df) +
## annotate with text, along your y
## by placing it beneath your geom_rect layer it will automatically be covered
geom_text(data = df_annot, aes(x, y, label = "|", angle = angle)) +
## move aes to the geom_layer
geom_rect(aes(ymax = end, ymin = start,
xmin = 0.8, xmax = 1,
fill = group)) +
coord_polar(theta = "y") +
xlim(c(0, 1))
Created on 2021-12-21 by the reprex package (v2.0.1)
You need to use panel.grid.minor.y instead of axis.ticks.y in order to change the ticks.
Your code will look like this:
base + theme(axis.ticks.y = element_blank(), axis.text.y = element_blank())
base + theme(panel.grid.minor.y = element_line(color = "black", size = 1))
The output will look like this:
I'm trying to add set of markers with text above the top of a faceted chart to indicate certain points of interest in the value of x. Its important that they appear in the right position left to right (as per the main scale), including when the overall ggplot changes size.
Something like this...
However, I'm struggling to:
place it in the right vertical position (above the facets). In my
reprex below (a simplified version of the original), I tried using a
value of the factor (Merc450 SLC), but this causes issues such as adding that to
every facet including when it is not part of that facet and doesn't
actually go high enough. I also tried converting the factor to a number using as.integer, but this causes every facet to include all factor values, when they obviously shouldn't
apply to the chart as a whole, not each
facet
Note that in the full solution, the marker x values are independent of the main data.
I have tried using cowplot to draw it separately and overlay it, but that seems to:
affect the overall scale of the main plot, with the facet titles on the right being cropped
is not reliable in placing the markers at the exact location along the x scale
Any pointers welcome.
library(tidyverse)
mtcars2 <- rownames_to_column(mtcars, var = "car") %>%
mutate(make = stringr::word(car, 1)) %>%
filter(make >= "m" & make < "n")
markers <- data.frame(x = c(max(mtcars2$mpg), rep(runif(nrow(mtcars2), 1, max(mtcars2$mpg))), max(mtcars2$mpg))) %>%
mutate(name = paste0("marker # ", round(x)))
ggplot(mtcars2, aes()) +
# Main Plot
geom_tile(aes(x = mpg, y = car, fill = cyl), color = "white") +
# Add Markers
geom_point(data = markers, aes(x = x, y = "Merc450 SLC"), color = "red") +
# Marker Labels
geom_text(data = markers, aes(x = x, "Merc450 SLC",label = name), angle = 45, size = 2.5, hjust=0, nudge_x = -0.02, nudge_y = 0.15) +
facet_grid(make ~ ., scales = "free", space = "free") +
theme_minimal() +
theme(
# Facets
strip.background = element_rect(fill="Gray90", color = "white"),
panel.background = element_rect(fill="Gray95", color = "white"),
panel.spacing.y = unit(.7, "lines"),
plot.margin = margin(50, 20, 20, 20)
)
Perhaps draw two separate plots and assemble them together with patchwork:
library(patchwork)
p1 <- ggplot(markers, aes(x = x, y = 0)) +
geom_point(color = 'red') +
geom_text(aes(label = name),
angle = 45, size = 2.5, hjust=0, nudge_x = -0.02, nudge_y = 0.02) +
scale_y_continuous(limits = c(-0.01, 0.15), expand = c(0, 0)) +
theme_minimal() +
theme(axis.text = element_blank(),
axis.title = element_blank(),
panel.grid = element_blank())
p2 <- ggplot(mtcars2, aes(x = mpg, y = car, fill = cyl)) +
geom_tile(color = "white") +
facet_grid(make ~ ., scales = "free", space = "free") +
theme_minimal() +
theme(
strip.background = element_rect(fill="Gray90", color = "white"),
panel.background = element_rect(fill="Gray95", color = "white"),
panel.spacing.y = unit(.7, "lines")
)
p1/p2 + plot_layout(heights = c(1, 9))
It required some workaround with plot on different plot and using cowplot alignment function to align them on the same axis. Here is a solution
library(tidyverse)
library(cowplot)
# define a common x_axis to ensure that the plot are on same scales
# This may not needed as cowplot algin_plots also adjust the scale however
# I tended to do this extra step to ensure.
x_axis_common <- c(min(mtcars2$mpg, markers$x) * .8,
max(mtcars2$mpg, markers$x) * 1.1)
# Plot contain only marker
plot_marker <- ggplot() +
geom_point(data = markers, aes(x = x, y = 0), color = "red") +
# Marker Labels
geom_text(data = markers, aes(x = x, y = 0,label = name),
angle = 45, size = 2.5, hjust=0, nudge_x = 0, nudge_y = 0.001) +
# using coord_cartesian to set the zone of plot for some scales
coord_cartesian(xlim = x_axis_common,
ylim = c(-0.005, 0.03), expand = FALSE) +
# using theme_nothing from cow_plot which remove all element
# except the drawing
theme_nothing()
# main plot with facet
main_plot <- ggplot(mtcars2, aes()) +
# Main Plot
geom_tile(aes(x = mpg, y = car, fill = cyl), color = "white") +
coord_cartesian(xlim = x_axis_common, expand = FALSE) +
# Add Markers
facet_grid(make ~ ., scales = "free_y", space = "free") +
theme_minimal() +
theme(
# Facets
strip.background = element_rect(fill="Gray90", color = "white"),
panel.background = element_rect(fill="Gray95", color = "white"),
panel.spacing.y = unit(.7, "lines"),
plot.margin = margin(0, 20, 20, 20)
)
Then align the plot and plot them using cow_plot
# align the plots together
temp <- align_plots(plot_marker, main_plot, axis = "rl",
align = "hv")
# plot them with plot_grid also from cowplot - using rel_heights for some
# adjustment
plot_grid(temp[[1]], temp[[2]], ncol = 1, rel_heights = c(1, 8))
Created on 2021-05-03 by the reprex package (v2.0.0)
I have the following code:
library(ggplot2)
library(gridExtra)
data = data.frame(fit = c(9.8,15.4,17.6,21.6,10.8), lower = c(7.15,12.75,14.95,18.95,8.15), upper = c(12.44,18.04,20.24,24.24,13.44), factors = c(15,20,25,30,35), var = rep("Fator", 5))
gp <- ggplot(data, aes(x=factors, y=fit, ymax=upper, ymin=lower))
gp <- gp + geom_line(aes(group=var),size=1.2) +
geom_errorbar(width=.8, size=1, aes(colour='red')) +
geom_point(size=4, shape=21, fill="grey") +
labs(x = paste("\n",data$var[1],sep=""), y =paste("Values","\n",sep="")) +
theme(legend.position = 'none', axis.text = element_text(size = 11), plot.margin=unit(c(0.4,0.4,0.4,0.4), "cm"), axis.text.x = element_text(angle=45, hjust = 1, vjust = 1)) +
ylim((min(data$lower)), (max(data$upper)))
I want to change the line color after I have the ggplot object. I'm trying:
gp + scale_color_manual(values = "green")
but it change the error bar color and not the line color.
1)What should I do to change the line color?
2)How can I change the points color?
Thanks!
Try this:
gp$layers[[1]] <- NULL
gp + geom_line(aes(group = var),color = "green",size = 1.2)
A similar technique should work for the points layer. Technique was dredged up from my memories of a similar question.
I just looked at the contents of gp$layers manually to see which was which. I presume that the order will be the order in which they appear in your code, but I wouldn't necessarily rely on that.