I am wondering how to configure Jupyter to plot a smaller figure within R kernel.
I have tried using options(repr.plot.width = 1, repr.plot.height = 0.75, repr.plot.res = 300), but the result is kinda messy. It is changing the size of the plot R produced. Are there any ways I can directly configure the output graph size in Jupyter.
In other words, how can I change the size in the first figure to the size in the second figure, while not messing up the plot.
You need to manually set the tick size, marker size and text size. The text size and tick size can be set through the theme() function, while marker size through geom_point() function.
df_1 = data.frame(x=c(5, 6, 7, 8, 9), y = c(200, 225, 250, 270, 310))
options(repr.plot.width = 1, repr.plot.height = 0.75)
ggplot(df_1, aes(x = x, y = y)) + geom_point(size = 0.3) +
theme(text = element_text(size = 3), element_line(size = 0.1))
You should simply change the resolution of your plot. For instance, try repr.plot.res = 100 in:
options(repr.plot.width = 1, repr.plot.height = 0.75, repr.plot.res = 100)
Related
I want to create venn diagrams to emphasize that groups (circles) are completely located inside one another, i.e., there are no elements in the inner circles that are not simutanously in outer circles.
I've used ggvenn and arrived at these results:
colonias <- c("colônias")
possessoes <- c("possessões", colonias)
dominios <- c("domínios", possessoes, colonias)
ggvenn(tipologia_britanica,
show_elements = T,
label_sep = "\n",
fill_color = brewer.pal(name="Dark2", n=3),
fill_alpha = 0.6,
stroke_size = 0.2,
stroke_alpha = 0.2,
set_name_size = 5,
text_size = 5)
The result is tchnically correct because it show that "colonias" are common to all three groups and that "possessoes" are common to both "possessoes" and "dominios". But graphically I would like te groups to be completely inside one another to show that are no elements in "colonias" that are not common to all three, and in "possessoes" that are not common to "dominios". I'm not sure that ggvenn package is capable of plotting that.
One way may use the package eulerr.
However, your question isn't very clear so I let you play with the package
See the example below :
library(eulerr)
fit <- euler(c("A" = 10, "B" = 10, "A&B" = 8, "A&B&C"=3))
plot(fit,
fills = list(fill = c("red", "steelblue4","green"), alpha = 0.5),
labels = list(col = "black", font = 4),quantities = T)
I don't think ggvenn allows a plot with this kind of relationship. However, it's not terribly difficult to draw it yourself with ggplot and geom_circle from ggforce
ggplot(data.frame(group = c("domínios", "possessões", "colônias"),
r = c(3, 2, 1)),
aes(x0 = 3 - r, y0 = 0, fill = factor(group, group))) +
geom_circle(aes(r = r), alpha = 1) +
geom_text(aes(x = c(0, 1, 2), y = c(2.3, 1.3, 0), label = group),
size = 8) +
scale_fill_manual(values = c('#77bca2', '#e1926b', '#a09cc8'),
guide = 'none') +
coord_equal() +
theme_void()
I am using image() and contour() to create a "heatmap" of probabilities - for example:
I was asked to change the labels such that they "do not overlap the lines, and the lines are unbroken." After consulting ?contour(), I tried changing to method = "edge" and method = "simple", but both fail print the labels (although the lines are unbroken), and cant seem to find posts regarding similar issues elsewhere.
Any advice on how to manipulate the labels to appear adjacent to (not on top of) unbroken lines would be much appreciated. I would prefer base R but also would welcome options from more flexible packages or alternative base R functions.
Minimal code to recreate example figure is here:
# Generate Data
Rs <- seq(0.02, 1.0, 0.005)
ks <- 10 ^ seq(-2.3, 0.5, 0.005)
prob <- function(Y,R,k) {
exp(lgamma(k*Y+Y-1) - lgamma(k*Y) - lgamma(Y+1) + (Y-1) * log(R/k) - (k*Y+Y-1) * log(1+R/k))
}
P05 <- matrix(NA, ncol = length(ks), nrow = length(Rs))
for(i in 1:length(Rs)) {
for(j in 1:length(ks)) {
P05[i,j] <- 1 - sum(prob(1:(5 - 1), Rs[i], ks[j]))
}
}
colfunc <- colorRampPalette(c("grey25", "grey90"))
lbreaks <- c(-1e-10, 1e-5, 1e-3, 5e-3, 1e-2, 2e-2, 5e-2, 1e-1, 1.5e-1, 1)
## Create Figure
image(Rs, ks, P05,
log="y", col = rev(colfunc(length(lbreaks)-1)), breaks = lbreaks, zlim = lbreaks,
ylim = c(min(ks), 2), xlim = c(0,1))
contour(Rs, ks, P05, levels = lbreaks, labcex = 1, add = TRUE)
There is an easy(ish) way to do this in ggplot, using the geomtextpath package.
First, convert your matrix to an x, y, z data frame:
df <- expand.grid(Rs = Rs, ks = ks)
df$z <- c(P05)
Now plot a filled contour, and then geom_textcontour. By default the text will break the lines, as in contour, but if you set the vjust above one or below zero the lines will close up as they don't need to break for the text.
I've added a few theme and scale elements to match the aesthetic of the base graphics function. Note the text and line size, color etc remain independently adjustable.
library(geomtextpath)
ggplot(df, aes(Rs, ks, z = z)) +
geom_contour_filled(breaks = lbreaks) +
geom_textcontour(breaks = lbreaks, color = 'black', size = 5,
aes(label = stat(level)), vjust = 1.2) +
scale_y_log10(breaks = c(0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2),
expand = c(0, 0)) +
scale_fill_manual(values = rev(colfunc(9)), guide = 'none') +
scale_x_continuous(expand = c(0, 0)) +
theme_classic(base_size = 16) +
theme(axis.text.y = element_text(angle = 90, hjust = 0.5),
axis.ticks.length.y = unit(3, 'mm'),
plot.margin = margin(20, 20, 20, 20))
The contour function is mostly written in C, and as far as I can see, it doesn't support the kinds of labels you want.
So I think there are two ways to do this, neither of which is very appealing:
Modify the source to the function. You can see the start of the labelling code here. I think you would need to rebuild R to incorporate your changes; it's not easy to move a function from a base package to a contributed package.
Draw the plot with no labels, and add them manually after the fact. You could add them using text(), or produce an output file and use an external program to edit the output file.
I am creating a multi panel figure that includes a ComplexHeatmap object so I am using multi_panel_figure() instead of ggarrange().
I have tried to include an argument to set the labels manually as I do in ggarrange but it does not work.
ggarrange(...,
font.label = list(size = 14, color = "black", face = "bold", family = NULL))
Like this:
Figure2 = multi_panel_figure(width = 360, height = 180,
columns = 3, rows = 1,
font.label = list(size = 24))
Figure2 %<>% fill_panel(DE_HM, column = 1)
Figure2 %<>% fill_panel(DE_TM, column = 2:3)
save_multi_panel_figure(figure = Figure2,
filename = "Figure2.svg")
I am quite new using ggplot2 so I do not know very well how to control the text size proportions. In this case I would like to make the labels bigger as I need to make the figure large so other text in it can be read easily. Maybe I should generate my figure any other way?
Here is how the labels look like right now (panel B need to be large so text can be read in the treemap):
With trace(fill_panel, edit=T) change the function fill_panel() on line 124 from:
panel_label <- textGrob(label = label, x = 1, y = 0, just = label_just)
to:
panel_label <- text_grob(label = label, x = 1, y = 0, just = label_just, face = "bold", size = 14)
also use library(ggpubr) in order to make this work.
I'm trying to convert my ggplot to a plotly plot using ggplotly(). However, it doesn't seem to work on this code, after manipulate is acted on the plot. Is there any other way to do it?
library(ggplot2)
library(manipulate)
grades <- data.frame(Final = 20 * runif(70))
myFinalsPlot <- function(sliderInput, initialIndex, finalIndex) {
ggplot(data.frame(grades$Final[initialIndex:finalIndex]),
aes(x = grades$Final[initialIndex:finalIndex])) +
geom_histogram(aes(y = ..density..),
binwidth = sliderInput, colour = "green", fill = "yellow") +
geom_density(alpha = 0.2, fill = "#FF6666") +
labs(x = "Marks", y = "Grades")
}
myFinalsPlot <- manipulate(myFinalsPlot(slidersInput, 1, 70),
slidersInput = slider(1, 12, step = 1, initial = 5))
First, to make your code work with the ggplot2 plot, there is an issue in your code that you need to fix. You shouldn't give the same name to your function and plot object. Replace this:
myFinalsPlot <- manipulate(myFinalsPlot(slidersInput, 1, 70),
slidersInput = slider(1, 12, step = 1, initial = 5))
By, e.g.:
myPlot <- manipulate(myFinalsPlot(slidersInput, 1, 70),
slidersInput = slider(1, 12, step = 1, initial = 5))
Now, regarding plotly plots, I don't think it is supposed to work with manipulate. I quote RStudio's website https://support.rstudio.com/hc/en-us/articles/200551906-Interactive-Plotting-with-Manipulate:
RStudio works with the manipulate package to add interactive capabilities to standard R plots.
I am trying to save a ggplot2 plot using the cairo_pdf() function, but the markers of the dotted geom_line() keep getting stretched. Please see sample code and output below.
library(ggplot2)
df <- data.frame(x = 0:10, y = 0:10)
p <- ggplot(data = df) +
geom_line(aes(x, y), linetype = 3, size = 2, lineend = "round")
ggsave("ggsave.pdf", width = 7, height = 5)
pdf("pdf.pdf", width = 7, height = 5)
print(p)
dev.off()
cairo_pdf("cairo_pdf.pdf", width = 7, height = 5)
print(p)
dev.off()
Output using ggsave() with markers nice and round:
Output using pdf() same as ggsave().
Output using cairo_pdf() with markers stretched and spacing between markers wrong:
Is there any way to make the cairo_pdf() output, specifically the geom_line(), look like the the other PDFs? I would like to use cairo_pdf() since it has some other benefits that really help with my work. Any help would be appreciated.
EDIT: I have the same problem using R base graphics. For instance:
pdf("r_base_pdf.pdf")
plot(x = c(0, 1), y = c(0, 1), type = "l", lty = "11", lwd = 5)
dev.off()
cairo_pdf("r_base_cairo.pdf")
plot(x = c(0, 1), y = c(0, 1), type = "l", lty = "11", lwd = 5)
dev.off()