It is possible to create inset graphs?ggplot put a plot inside of another plot?Embedding a subplot in ggplot (ggsubplot)How can you get ggplot2 to display an inset figure when the main one has a log scale?Combine scatter plot with rotated histogram of residuals in Rggplot2 fix overlapping y-labelsPlot two graphs in same plot in RHow can I handle R CMD check “no visible binding for global variable” notes when my ggplot2 syntax is sensible?How can we make xkcd style graphs?Create a stacked density graph in ggplot2create templates using ggplot2 syntax?data.table vs dplyr: can one do something well the other can't or does poorly?Is it possible to create a line graph in r, where the colour of the line changes at a specific pointIn R, how can I store an inset graph for later arranging it with grid.arrange?inset map using ggplot2
How to illustrate the Mean Value theorem?
Have 1.5% of all nuclear reactors ever built melted down?
What does this symbol on the box of power supply mean?
Should breaking down something like a door be adjudicated as an attempt to beat its AC and HP, or as an ability check against a set DC?
what kind of chord progession is this?
Is the derivative with respect to a fermion field Grassmann-odd?
Did people Unsnap to where they were?
How do I partition a matrx into blocks and replace zeros with dots?
What are these arcade games in Ghostbusters 1984?
C++ forcing function parameter evalution order
Using credit/debit card details vs swiping a card in a payment (credit card) terminal
What is this opening/position called, and what is white’s best move?
Who will lead the country until there is a new Tory leader?
Is the taxi route omitted in low visibility (LVP)?
At what point in European history could a government build a printing press given a basic description?
Make 24 using exactly three 3s
Inconsistent results from Wolfram Could
Any advice on creating fictional locations in real places when writing historical fiction?
Would Jetfuel for a modern jet like an F-16 or a F-35 be producable in the WW2 era?
What is Theresa May waiting for?
My players want to grind XP but we're using milestone advancement
Boss wants me to falsify a report. How should I document this unethical demand?
Grammar Question Regarding "Are the" or "Is the" When Referring to Something that May or May not be Plural
Gladys goes shopping
It is possible to create inset graphs?
ggplot put a plot inside of another plot?Embedding a subplot in ggplot (ggsubplot)How can you get ggplot2 to display an inset figure when the main one has a log scale?Combine scatter plot with rotated histogram of residuals in Rggplot2 fix overlapping y-labelsPlot two graphs in same plot in RHow can I handle R CMD check “no visible binding for global variable” notes when my ggplot2 syntax is sensible?How can we make xkcd style graphs?Create a stacked density graph in ggplot2create templates using ggplot2 syntax?data.table vs dplyr: can one do something well the other can't or does poorly?Is it possible to create a line graph in r, where the colour of the line changes at a specific pointIn R, how can I store an inset graph for later arranging it with grid.arrange?inset map using ggplot2
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I know that when you use par( fig=c( ... ), new=T )
, you can create inset graphs. However, I was wondering if it is possible to use ggplot2 library to create 'inset' graphs.
UPDATE 1: I tried using the par()
with ggplot2, but it does not work.
UPDATE 2: I found a working solution at ggplot2 GoogleGroups using grid::viewport()
.
r graphics ggplot2 insets
add a comment |
I know that when you use par( fig=c( ... ), new=T )
, you can create inset graphs. However, I was wondering if it is possible to use ggplot2 library to create 'inset' graphs.
UPDATE 1: I tried using the par()
with ggplot2, but it does not work.
UPDATE 2: I found a working solution at ggplot2 GoogleGroups using grid::viewport()
.
r graphics ggplot2 insets
1
This post on the Learning R blog goes over how to plot inside a plot. The blog has a lot of other great posts on ggplot2.
– Erik Shilts
Mar 7 '11 at 15:03
add a comment |
I know that when you use par( fig=c( ... ), new=T )
, you can create inset graphs. However, I was wondering if it is possible to use ggplot2 library to create 'inset' graphs.
UPDATE 1: I tried using the par()
with ggplot2, but it does not work.
UPDATE 2: I found a working solution at ggplot2 GoogleGroups using grid::viewport()
.
r graphics ggplot2 insets
I know that when you use par( fig=c( ... ), new=T )
, you can create inset graphs. However, I was wondering if it is possible to use ggplot2 library to create 'inset' graphs.
UPDATE 1: I tried using the par()
with ggplot2, but it does not work.
UPDATE 2: I found a working solution at ggplot2 GoogleGroups using grid::viewport()
.
r graphics ggplot2 insets
r graphics ggplot2 insets
edited Aug 19 '16 at 21:00
zx8754
31.6k768108
31.6k768108
asked Mar 7 '11 at 12:21
SamSam
3,020113756
3,020113756
1
This post on the Learning R blog goes over how to plot inside a plot. The blog has a lot of other great posts on ggplot2.
– Erik Shilts
Mar 7 '11 at 15:03
add a comment |
1
This post on the Learning R blog goes over how to plot inside a plot. The blog has a lot of other great posts on ggplot2.
– Erik Shilts
Mar 7 '11 at 15:03
1
1
This post on the Learning R blog goes over how to plot inside a plot. The blog has a lot of other great posts on ggplot2.
– Erik Shilts
Mar 7 '11 at 15:03
This post on the Learning R blog goes over how to plot inside a plot. The blog has a lot of other great posts on ggplot2.
– Erik Shilts
Mar 7 '11 at 15:03
add a comment |
5 Answers
5
active
oldest
votes
Section 8.4 of the book explains how to do this. The trick is to use the grid
package's viewport
s.
#Any old plot
a_plot <- ggplot(cars, aes(speed, dist)) + geom_line()
#A viewport taking up a fraction of the plot area
vp <- viewport(width = 0.4, height = 0.4, x = 0.8, y = 0.2)
#Just draw the plot twice
png("test.png")
print(a_plot)
print(a_plot, vp = vp)
dev.off()
2
Worth pointing out that, if one wants another plot as the inset, the crucial line is to beprint(another_plot, vp = vp)
. It took me a while to figure out. +1
– mts
Apr 9 '17 at 20:44
add a comment |
I prefer solutions that work with ggsave. After a lot of googling around I ended up with this (which is a general formula for positioning and sizing the plot that you insert.
library(tidyverse)
plot1 = qplot(1.00*mpg, 1.00*wt, data=mtcars) # Make sure x and y values are floating values in plot 1
plot2 = qplot(hp, cyl, data=mtcars)
plot(plot1)
# Specify position of plot2 (in percentages of plot1)
# This is in the top left and 25% width and 25% height
xleft = 0.05
xright = 0.30
ybottom = 0.70
ytop = 0.95
# Calculate position in plot1 coordinates
# Extract x and y values from plot1
l1 = ggplot_build(plot1)
x1 = l1$layout$panel_ranges[[1]]$x.range[1]
x2 = l1$layout$panel_ranges[[1]]$x.range[2]
y1 = l1$layout$panel_ranges[[1]]$y.range[1]
y2 = l1$layout$panel_ranges[[1]]$y.range[2]
xdif = x2-x1
ydif = y2-y1
xmin = x1 + (xleft*xdif)
xmax = x1 + (xright*xdif)
ymin = y1 + (ybottom*ydif)
ymax = y1 + (ytop*ydif)
# Get plot2 and make grob
g2 = ggplotGrob(plot2)
plot3 = plot1 + annotation_custom(grob = g2, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
plot(plot3)
ggsave(filename = "test.png", plot = plot3)
# Try and make a weird combination of plots
g1 <- ggplotGrob(plot1)
g2 <- ggplotGrob(plot2)
g3 <- ggplotGrob(plot3)
library(gridExtra)
library(grid)
t1 = arrangeGrob(g1,ncol=1, left = textGrob("A", y = 1, vjust=1, gp=gpar(fontsize=20)))
t2 = arrangeGrob(g2,ncol=1, left = textGrob("B", y = 1, vjust=1, gp=gpar(fontsize=20)))
t3 = arrangeGrob(g3,ncol=1, left = textGrob("C", y = 1, vjust=1, gp=gpar(fontsize=20)))
final = arrangeGrob(t1,t2,t3, layout_matrix = cbind(c(1,2), c(3,3)))
grid.arrange(final)
ggsave(filename = "test2.png", plot = final)
1
I think they've updated the ggplot package and now, in order to extract the position from the plot1 coordinates the format should be like this:l1$layout$panel_ranges[[1]]$x.range[1]
. Note thel1$layout$panel_ranges....
– s_scolary
Dec 4 '17 at 21:39
You are right. I have updated the answer accordingly.
– pallevillesen
Dec 14 '17 at 9:42
add a comment |
Much simpler solution utilizing ggplot2
and egg
. Most importantly this solution works with ggsave
.
library(tidyverse)
library(egg)
plotx <- ggplot(mpg, aes(displ, hwy)) + geom_point()
plotx +
annotation_custom(
ggplotGrob(plotx),
xmin = 5, xmax = 7, ymin = 30, ymax = 44
)
ggsave(filename = "inset-plot.png")
5
Hey @stackinator. +1 for concise example and mentioning theegg
package. Note that just usinglibrary(ggplot2)
is more than enough (one does not need the extratidyverse
noregg
)
– Valentin
Aug 14 '18 at 19:26
add a comment |
Alternatively, can use the cowplot
R package by Claus O. Wilke (cowplot
is a powerful extension of ggplot2
). The author has an example about plotting an inset inside a larger graph in this intro vignette. Here is some adapted code:
library(cowplot)
main.plot <-
ggplot(data = mpg, aes(x = cty, y = hwy, colour = factor(cyl))) +
geom_point(size = 2.5)
inset.plot <- main.plot + theme(legend.position = "none")
plot.with.inset <-
ggdraw() +
draw_plot(main.plot) +
draw_plot(inset.plot, x = 0.07, y = .7, width = .3, height = .3)
# Can save the plot with ggsave()
ggsave(filename = "plot.with.inset.png",
plot = plot.with.inset,
width = 17,
height = 12,
units = "cm",
dpi = 300)
I think you can also passmain.plot
toggdraw()
to save one line of code.
– crsh
May 3 at 10:27
add a comment |
'ggplot2' >= 3.0.0 makes possible new approaches for adding insets, as now tibble
objects containing lists as member columns can be passed as data. The objects in the list column can be even whole ggplots... The latest version of my package 'ggpmisc' provides geom_plot()
, geom_table()
and geom_grob()
, and also versions that use npc units instead of native data units for locating the insets. These geoms can add multiple insets per call and obey faceting, which annotation_custom()
does not. I copy the example from the help page, which adds an inset with a zoom-in detail of the main plot as an inset.
library(tibble)
library(ggpmisc)
p <-
ggplot(data = mtcars, mapping = aes(wt, mpg)) +
geom_point()
df <- tibble(x = 0.01, y = 0.01,
plot = list(p +
coord_cartesian(xlim = c(3, 4),
ylim = c(13, 16)) +
labs(x = NULL, y = NULL) +
theme_bw(10)))
p +
expand_limits(x = 0, y = 0) +
geom_plot_npc(data = df, aes(npcx = x, npcy = y, label = plot))
Or a barplot as inset, taken from the package vignette.
library(tibble)
library(ggpmisc)
p <- ggplot(mpg, aes(factor(cyl), hwy, fill = factor(cyl))) +
stat_summary(geom = "col", fun.y = mean, width = 2/3) +
labs(x = "Number of cylinders", y = NULL, title = "Means") +
scale_fill_discrete(guide = FALSE)
data.tb <- tibble(x = 7, y = 44,
plot = list(p +
theme_bw(8)))
ggplot(mpg, aes(displ, hwy, colour = factor(cyl))) +
geom_plot(data = data.tb, aes(x, y, label = plot)) +
geom_point() +
labs(x = "Engine displacement (l)", y = "Fuel use efficiency (MPG)",
colour = "Engine cylindersn(number)") +
theme_bw()
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5219671%2fit-is-possible-to-create-inset-graphs%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
Section 8.4 of the book explains how to do this. The trick is to use the grid
package's viewport
s.
#Any old plot
a_plot <- ggplot(cars, aes(speed, dist)) + geom_line()
#A viewport taking up a fraction of the plot area
vp <- viewport(width = 0.4, height = 0.4, x = 0.8, y = 0.2)
#Just draw the plot twice
png("test.png")
print(a_plot)
print(a_plot, vp = vp)
dev.off()
2
Worth pointing out that, if one wants another plot as the inset, the crucial line is to beprint(another_plot, vp = vp)
. It took me a while to figure out. +1
– mts
Apr 9 '17 at 20:44
add a comment |
Section 8.4 of the book explains how to do this. The trick is to use the grid
package's viewport
s.
#Any old plot
a_plot <- ggplot(cars, aes(speed, dist)) + geom_line()
#A viewport taking up a fraction of the plot area
vp <- viewport(width = 0.4, height = 0.4, x = 0.8, y = 0.2)
#Just draw the plot twice
png("test.png")
print(a_plot)
print(a_plot, vp = vp)
dev.off()
2
Worth pointing out that, if one wants another plot as the inset, the crucial line is to beprint(another_plot, vp = vp)
. It took me a while to figure out. +1
– mts
Apr 9 '17 at 20:44
add a comment |
Section 8.4 of the book explains how to do this. The trick is to use the grid
package's viewport
s.
#Any old plot
a_plot <- ggplot(cars, aes(speed, dist)) + geom_line()
#A viewport taking up a fraction of the plot area
vp <- viewport(width = 0.4, height = 0.4, x = 0.8, y = 0.2)
#Just draw the plot twice
png("test.png")
print(a_plot)
print(a_plot, vp = vp)
dev.off()
Section 8.4 of the book explains how to do this. The trick is to use the grid
package's viewport
s.
#Any old plot
a_plot <- ggplot(cars, aes(speed, dist)) + geom_line()
#A viewport taking up a fraction of the plot area
vp <- viewport(width = 0.4, height = 0.4, x = 0.8, y = 0.2)
#Just draw the plot twice
png("test.png")
print(a_plot)
print(a_plot, vp = vp)
dev.off()
edited Mar 24 at 3:47
Jessica Burnett
17110
17110
answered Mar 7 '11 at 14:06
Richie CottonRichie Cotton
82.1k30192313
82.1k30192313
2
Worth pointing out that, if one wants another plot as the inset, the crucial line is to beprint(another_plot, vp = vp)
. It took me a while to figure out. +1
– mts
Apr 9 '17 at 20:44
add a comment |
2
Worth pointing out that, if one wants another plot as the inset, the crucial line is to beprint(another_plot, vp = vp)
. It took me a while to figure out. +1
– mts
Apr 9 '17 at 20:44
2
2
Worth pointing out that, if one wants another plot as the inset, the crucial line is to be
print(another_plot, vp = vp)
. It took me a while to figure out. +1– mts
Apr 9 '17 at 20:44
Worth pointing out that, if one wants another plot as the inset, the crucial line is to be
print(another_plot, vp = vp)
. It took me a while to figure out. +1– mts
Apr 9 '17 at 20:44
add a comment |
I prefer solutions that work with ggsave. After a lot of googling around I ended up with this (which is a general formula for positioning and sizing the plot that you insert.
library(tidyverse)
plot1 = qplot(1.00*mpg, 1.00*wt, data=mtcars) # Make sure x and y values are floating values in plot 1
plot2 = qplot(hp, cyl, data=mtcars)
plot(plot1)
# Specify position of plot2 (in percentages of plot1)
# This is in the top left and 25% width and 25% height
xleft = 0.05
xright = 0.30
ybottom = 0.70
ytop = 0.95
# Calculate position in plot1 coordinates
# Extract x and y values from plot1
l1 = ggplot_build(plot1)
x1 = l1$layout$panel_ranges[[1]]$x.range[1]
x2 = l1$layout$panel_ranges[[1]]$x.range[2]
y1 = l1$layout$panel_ranges[[1]]$y.range[1]
y2 = l1$layout$panel_ranges[[1]]$y.range[2]
xdif = x2-x1
ydif = y2-y1
xmin = x1 + (xleft*xdif)
xmax = x1 + (xright*xdif)
ymin = y1 + (ybottom*ydif)
ymax = y1 + (ytop*ydif)
# Get plot2 and make grob
g2 = ggplotGrob(plot2)
plot3 = plot1 + annotation_custom(grob = g2, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
plot(plot3)
ggsave(filename = "test.png", plot = plot3)
# Try and make a weird combination of plots
g1 <- ggplotGrob(plot1)
g2 <- ggplotGrob(plot2)
g3 <- ggplotGrob(plot3)
library(gridExtra)
library(grid)
t1 = arrangeGrob(g1,ncol=1, left = textGrob("A", y = 1, vjust=1, gp=gpar(fontsize=20)))
t2 = arrangeGrob(g2,ncol=1, left = textGrob("B", y = 1, vjust=1, gp=gpar(fontsize=20)))
t3 = arrangeGrob(g3,ncol=1, left = textGrob("C", y = 1, vjust=1, gp=gpar(fontsize=20)))
final = arrangeGrob(t1,t2,t3, layout_matrix = cbind(c(1,2), c(3,3)))
grid.arrange(final)
ggsave(filename = "test2.png", plot = final)
1
I think they've updated the ggplot package and now, in order to extract the position from the plot1 coordinates the format should be like this:l1$layout$panel_ranges[[1]]$x.range[1]
. Note thel1$layout$panel_ranges....
– s_scolary
Dec 4 '17 at 21:39
You are right. I have updated the answer accordingly.
– pallevillesen
Dec 14 '17 at 9:42
add a comment |
I prefer solutions that work with ggsave. After a lot of googling around I ended up with this (which is a general formula for positioning and sizing the plot that you insert.
library(tidyverse)
plot1 = qplot(1.00*mpg, 1.00*wt, data=mtcars) # Make sure x and y values are floating values in plot 1
plot2 = qplot(hp, cyl, data=mtcars)
plot(plot1)
# Specify position of plot2 (in percentages of plot1)
# This is in the top left and 25% width and 25% height
xleft = 0.05
xright = 0.30
ybottom = 0.70
ytop = 0.95
# Calculate position in plot1 coordinates
# Extract x and y values from plot1
l1 = ggplot_build(plot1)
x1 = l1$layout$panel_ranges[[1]]$x.range[1]
x2 = l1$layout$panel_ranges[[1]]$x.range[2]
y1 = l1$layout$panel_ranges[[1]]$y.range[1]
y2 = l1$layout$panel_ranges[[1]]$y.range[2]
xdif = x2-x1
ydif = y2-y1
xmin = x1 + (xleft*xdif)
xmax = x1 + (xright*xdif)
ymin = y1 + (ybottom*ydif)
ymax = y1 + (ytop*ydif)
# Get plot2 and make grob
g2 = ggplotGrob(plot2)
plot3 = plot1 + annotation_custom(grob = g2, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
plot(plot3)
ggsave(filename = "test.png", plot = plot3)
# Try and make a weird combination of plots
g1 <- ggplotGrob(plot1)
g2 <- ggplotGrob(plot2)
g3 <- ggplotGrob(plot3)
library(gridExtra)
library(grid)
t1 = arrangeGrob(g1,ncol=1, left = textGrob("A", y = 1, vjust=1, gp=gpar(fontsize=20)))
t2 = arrangeGrob(g2,ncol=1, left = textGrob("B", y = 1, vjust=1, gp=gpar(fontsize=20)))
t3 = arrangeGrob(g3,ncol=1, left = textGrob("C", y = 1, vjust=1, gp=gpar(fontsize=20)))
final = arrangeGrob(t1,t2,t3, layout_matrix = cbind(c(1,2), c(3,3)))
grid.arrange(final)
ggsave(filename = "test2.png", plot = final)
1
I think they've updated the ggplot package and now, in order to extract the position from the plot1 coordinates the format should be like this:l1$layout$panel_ranges[[1]]$x.range[1]
. Note thel1$layout$panel_ranges....
– s_scolary
Dec 4 '17 at 21:39
You are right. I have updated the answer accordingly.
– pallevillesen
Dec 14 '17 at 9:42
add a comment |
I prefer solutions that work with ggsave. After a lot of googling around I ended up with this (which is a general formula for positioning and sizing the plot that you insert.
library(tidyverse)
plot1 = qplot(1.00*mpg, 1.00*wt, data=mtcars) # Make sure x and y values are floating values in plot 1
plot2 = qplot(hp, cyl, data=mtcars)
plot(plot1)
# Specify position of plot2 (in percentages of plot1)
# This is in the top left and 25% width and 25% height
xleft = 0.05
xright = 0.30
ybottom = 0.70
ytop = 0.95
# Calculate position in plot1 coordinates
# Extract x and y values from plot1
l1 = ggplot_build(plot1)
x1 = l1$layout$panel_ranges[[1]]$x.range[1]
x2 = l1$layout$panel_ranges[[1]]$x.range[2]
y1 = l1$layout$panel_ranges[[1]]$y.range[1]
y2 = l1$layout$panel_ranges[[1]]$y.range[2]
xdif = x2-x1
ydif = y2-y1
xmin = x1 + (xleft*xdif)
xmax = x1 + (xright*xdif)
ymin = y1 + (ybottom*ydif)
ymax = y1 + (ytop*ydif)
# Get plot2 and make grob
g2 = ggplotGrob(plot2)
plot3 = plot1 + annotation_custom(grob = g2, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
plot(plot3)
ggsave(filename = "test.png", plot = plot3)
# Try and make a weird combination of plots
g1 <- ggplotGrob(plot1)
g2 <- ggplotGrob(plot2)
g3 <- ggplotGrob(plot3)
library(gridExtra)
library(grid)
t1 = arrangeGrob(g1,ncol=1, left = textGrob("A", y = 1, vjust=1, gp=gpar(fontsize=20)))
t2 = arrangeGrob(g2,ncol=1, left = textGrob("B", y = 1, vjust=1, gp=gpar(fontsize=20)))
t3 = arrangeGrob(g3,ncol=1, left = textGrob("C", y = 1, vjust=1, gp=gpar(fontsize=20)))
final = arrangeGrob(t1,t2,t3, layout_matrix = cbind(c(1,2), c(3,3)))
grid.arrange(final)
ggsave(filename = "test2.png", plot = final)
I prefer solutions that work with ggsave. After a lot of googling around I ended up with this (which is a general formula for positioning and sizing the plot that you insert.
library(tidyverse)
plot1 = qplot(1.00*mpg, 1.00*wt, data=mtcars) # Make sure x and y values are floating values in plot 1
plot2 = qplot(hp, cyl, data=mtcars)
plot(plot1)
# Specify position of plot2 (in percentages of plot1)
# This is in the top left and 25% width and 25% height
xleft = 0.05
xright = 0.30
ybottom = 0.70
ytop = 0.95
# Calculate position in plot1 coordinates
# Extract x and y values from plot1
l1 = ggplot_build(plot1)
x1 = l1$layout$panel_ranges[[1]]$x.range[1]
x2 = l1$layout$panel_ranges[[1]]$x.range[2]
y1 = l1$layout$panel_ranges[[1]]$y.range[1]
y2 = l1$layout$panel_ranges[[1]]$y.range[2]
xdif = x2-x1
ydif = y2-y1
xmin = x1 + (xleft*xdif)
xmax = x1 + (xright*xdif)
ymin = y1 + (ybottom*ydif)
ymax = y1 + (ytop*ydif)
# Get plot2 and make grob
g2 = ggplotGrob(plot2)
plot3 = plot1 + annotation_custom(grob = g2, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax)
plot(plot3)
ggsave(filename = "test.png", plot = plot3)
# Try and make a weird combination of plots
g1 <- ggplotGrob(plot1)
g2 <- ggplotGrob(plot2)
g3 <- ggplotGrob(plot3)
library(gridExtra)
library(grid)
t1 = arrangeGrob(g1,ncol=1, left = textGrob("A", y = 1, vjust=1, gp=gpar(fontsize=20)))
t2 = arrangeGrob(g2,ncol=1, left = textGrob("B", y = 1, vjust=1, gp=gpar(fontsize=20)))
t3 = arrangeGrob(g3,ncol=1, left = textGrob("C", y = 1, vjust=1, gp=gpar(fontsize=20)))
final = arrangeGrob(t1,t2,t3, layout_matrix = cbind(c(1,2), c(3,3)))
grid.arrange(final)
ggsave(filename = "test2.png", plot = final)
edited Dec 14 '17 at 9:43
answered Jun 16 '16 at 11:15
pallevillesenpallevillesen
505313
505313
1
I think they've updated the ggplot package and now, in order to extract the position from the plot1 coordinates the format should be like this:l1$layout$panel_ranges[[1]]$x.range[1]
. Note thel1$layout$panel_ranges....
– s_scolary
Dec 4 '17 at 21:39
You are right. I have updated the answer accordingly.
– pallevillesen
Dec 14 '17 at 9:42
add a comment |
1
I think they've updated the ggplot package and now, in order to extract the position from the plot1 coordinates the format should be like this:l1$layout$panel_ranges[[1]]$x.range[1]
. Note thel1$layout$panel_ranges....
– s_scolary
Dec 4 '17 at 21:39
You are right. I have updated the answer accordingly.
– pallevillesen
Dec 14 '17 at 9:42
1
1
I think they've updated the ggplot package and now, in order to extract the position from the plot1 coordinates the format should be like this:
l1$layout$panel_ranges[[1]]$x.range[1]
. Note the l1$layout$panel_ranges....
– s_scolary
Dec 4 '17 at 21:39
I think they've updated the ggplot package and now, in order to extract the position from the plot1 coordinates the format should be like this:
l1$layout$panel_ranges[[1]]$x.range[1]
. Note the l1$layout$panel_ranges....
– s_scolary
Dec 4 '17 at 21:39
You are right. I have updated the answer accordingly.
– pallevillesen
Dec 14 '17 at 9:42
You are right. I have updated the answer accordingly.
– pallevillesen
Dec 14 '17 at 9:42
add a comment |
Much simpler solution utilizing ggplot2
and egg
. Most importantly this solution works with ggsave
.
library(tidyverse)
library(egg)
plotx <- ggplot(mpg, aes(displ, hwy)) + geom_point()
plotx +
annotation_custom(
ggplotGrob(plotx),
xmin = 5, xmax = 7, ymin = 30, ymax = 44
)
ggsave(filename = "inset-plot.png")
5
Hey @stackinator. +1 for concise example and mentioning theegg
package. Note that just usinglibrary(ggplot2)
is more than enough (one does not need the extratidyverse
noregg
)
– Valentin
Aug 14 '18 at 19:26
add a comment |
Much simpler solution utilizing ggplot2
and egg
. Most importantly this solution works with ggsave
.
library(tidyverse)
library(egg)
plotx <- ggplot(mpg, aes(displ, hwy)) + geom_point()
plotx +
annotation_custom(
ggplotGrob(plotx),
xmin = 5, xmax = 7, ymin = 30, ymax = 44
)
ggsave(filename = "inset-plot.png")
5
Hey @stackinator. +1 for concise example and mentioning theegg
package. Note that just usinglibrary(ggplot2)
is more than enough (one does not need the extratidyverse
noregg
)
– Valentin
Aug 14 '18 at 19:26
add a comment |
Much simpler solution utilizing ggplot2
and egg
. Most importantly this solution works with ggsave
.
library(tidyverse)
library(egg)
plotx <- ggplot(mpg, aes(displ, hwy)) + geom_point()
plotx +
annotation_custom(
ggplotGrob(plotx),
xmin = 5, xmax = 7, ymin = 30, ymax = 44
)
ggsave(filename = "inset-plot.png")
Much simpler solution utilizing ggplot2
and egg
. Most importantly this solution works with ggsave
.
library(tidyverse)
library(egg)
plotx <- ggplot(mpg, aes(displ, hwy)) + geom_point()
plotx +
annotation_custom(
ggplotGrob(plotx),
xmin = 5, xmax = 7, ymin = 30, ymax = 44
)
ggsave(filename = "inset-plot.png")
edited Sep 11 '18 at 11:20
answered Jun 15 '18 at 13:30
stackinatorstackinator
1,3641825
1,3641825
5
Hey @stackinator. +1 for concise example and mentioning theegg
package. Note that just usinglibrary(ggplot2)
is more than enough (one does not need the extratidyverse
noregg
)
– Valentin
Aug 14 '18 at 19:26
add a comment |
5
Hey @stackinator. +1 for concise example and mentioning theegg
package. Note that just usinglibrary(ggplot2)
is more than enough (one does not need the extratidyverse
noregg
)
– Valentin
Aug 14 '18 at 19:26
5
5
Hey @stackinator. +1 for concise example and mentioning the
egg
package. Note that just using library(ggplot2)
is more than enough (one does not need the extra tidyverse
nor egg
)– Valentin
Aug 14 '18 at 19:26
Hey @stackinator. +1 for concise example and mentioning the
egg
package. Note that just using library(ggplot2)
is more than enough (one does not need the extra tidyverse
nor egg
)– Valentin
Aug 14 '18 at 19:26
add a comment |
Alternatively, can use the cowplot
R package by Claus O. Wilke (cowplot
is a powerful extension of ggplot2
). The author has an example about plotting an inset inside a larger graph in this intro vignette. Here is some adapted code:
library(cowplot)
main.plot <-
ggplot(data = mpg, aes(x = cty, y = hwy, colour = factor(cyl))) +
geom_point(size = 2.5)
inset.plot <- main.plot + theme(legend.position = "none")
plot.with.inset <-
ggdraw() +
draw_plot(main.plot) +
draw_plot(inset.plot, x = 0.07, y = .7, width = .3, height = .3)
# Can save the plot with ggsave()
ggsave(filename = "plot.with.inset.png",
plot = plot.with.inset,
width = 17,
height = 12,
units = "cm",
dpi = 300)
I think you can also passmain.plot
toggdraw()
to save one line of code.
– crsh
May 3 at 10:27
add a comment |
Alternatively, can use the cowplot
R package by Claus O. Wilke (cowplot
is a powerful extension of ggplot2
). The author has an example about plotting an inset inside a larger graph in this intro vignette. Here is some adapted code:
library(cowplot)
main.plot <-
ggplot(data = mpg, aes(x = cty, y = hwy, colour = factor(cyl))) +
geom_point(size = 2.5)
inset.plot <- main.plot + theme(legend.position = "none")
plot.with.inset <-
ggdraw() +
draw_plot(main.plot) +
draw_plot(inset.plot, x = 0.07, y = .7, width = .3, height = .3)
# Can save the plot with ggsave()
ggsave(filename = "plot.with.inset.png",
plot = plot.with.inset,
width = 17,
height = 12,
units = "cm",
dpi = 300)
I think you can also passmain.plot
toggdraw()
to save one line of code.
– crsh
May 3 at 10:27
add a comment |
Alternatively, can use the cowplot
R package by Claus O. Wilke (cowplot
is a powerful extension of ggplot2
). The author has an example about plotting an inset inside a larger graph in this intro vignette. Here is some adapted code:
library(cowplot)
main.plot <-
ggplot(data = mpg, aes(x = cty, y = hwy, colour = factor(cyl))) +
geom_point(size = 2.5)
inset.plot <- main.plot + theme(legend.position = "none")
plot.with.inset <-
ggdraw() +
draw_plot(main.plot) +
draw_plot(inset.plot, x = 0.07, y = .7, width = .3, height = .3)
# Can save the plot with ggsave()
ggsave(filename = "plot.with.inset.png",
plot = plot.with.inset,
width = 17,
height = 12,
units = "cm",
dpi = 300)
Alternatively, can use the cowplot
R package by Claus O. Wilke (cowplot
is a powerful extension of ggplot2
). The author has an example about plotting an inset inside a larger graph in this intro vignette. Here is some adapted code:
library(cowplot)
main.plot <-
ggplot(data = mpg, aes(x = cty, y = hwy, colour = factor(cyl))) +
geom_point(size = 2.5)
inset.plot <- main.plot + theme(legend.position = "none")
plot.with.inset <-
ggdraw() +
draw_plot(main.plot) +
draw_plot(inset.plot, x = 0.07, y = .7, width = .3, height = .3)
# Can save the plot with ggsave()
ggsave(filename = "plot.with.inset.png",
plot = plot.with.inset,
width = 17,
height = 12,
units = "cm",
dpi = 300)
answered Oct 16 '18 at 18:21
ValentinValentin
2,4491732
2,4491732
I think you can also passmain.plot
toggdraw()
to save one line of code.
– crsh
May 3 at 10:27
add a comment |
I think you can also passmain.plot
toggdraw()
to save one line of code.
– crsh
May 3 at 10:27
I think you can also pass
main.plot
to ggdraw()
to save one line of code.– crsh
May 3 at 10:27
I think you can also pass
main.plot
to ggdraw()
to save one line of code.– crsh
May 3 at 10:27
add a comment |
'ggplot2' >= 3.0.0 makes possible new approaches for adding insets, as now tibble
objects containing lists as member columns can be passed as data. The objects in the list column can be even whole ggplots... The latest version of my package 'ggpmisc' provides geom_plot()
, geom_table()
and geom_grob()
, and also versions that use npc units instead of native data units for locating the insets. These geoms can add multiple insets per call and obey faceting, which annotation_custom()
does not. I copy the example from the help page, which adds an inset with a zoom-in detail of the main plot as an inset.
library(tibble)
library(ggpmisc)
p <-
ggplot(data = mtcars, mapping = aes(wt, mpg)) +
geom_point()
df <- tibble(x = 0.01, y = 0.01,
plot = list(p +
coord_cartesian(xlim = c(3, 4),
ylim = c(13, 16)) +
labs(x = NULL, y = NULL) +
theme_bw(10)))
p +
expand_limits(x = 0, y = 0) +
geom_plot_npc(data = df, aes(npcx = x, npcy = y, label = plot))
Or a barplot as inset, taken from the package vignette.
library(tibble)
library(ggpmisc)
p <- ggplot(mpg, aes(factor(cyl), hwy, fill = factor(cyl))) +
stat_summary(geom = "col", fun.y = mean, width = 2/3) +
labs(x = "Number of cylinders", y = NULL, title = "Means") +
scale_fill_discrete(guide = FALSE)
data.tb <- tibble(x = 7, y = 44,
plot = list(p +
theme_bw(8)))
ggplot(mpg, aes(displ, hwy, colour = factor(cyl))) +
geom_plot(data = data.tb, aes(x, y, label = plot)) +
geom_point() +
labs(x = "Engine displacement (l)", y = "Fuel use efficiency (MPG)",
colour = "Engine cylindersn(number)") +
theme_bw()
add a comment |
'ggplot2' >= 3.0.0 makes possible new approaches for adding insets, as now tibble
objects containing lists as member columns can be passed as data. The objects in the list column can be even whole ggplots... The latest version of my package 'ggpmisc' provides geom_plot()
, geom_table()
and geom_grob()
, and also versions that use npc units instead of native data units for locating the insets. These geoms can add multiple insets per call and obey faceting, which annotation_custom()
does not. I copy the example from the help page, which adds an inset with a zoom-in detail of the main plot as an inset.
library(tibble)
library(ggpmisc)
p <-
ggplot(data = mtcars, mapping = aes(wt, mpg)) +
geom_point()
df <- tibble(x = 0.01, y = 0.01,
plot = list(p +
coord_cartesian(xlim = c(3, 4),
ylim = c(13, 16)) +
labs(x = NULL, y = NULL) +
theme_bw(10)))
p +
expand_limits(x = 0, y = 0) +
geom_plot_npc(data = df, aes(npcx = x, npcy = y, label = plot))
Or a barplot as inset, taken from the package vignette.
library(tibble)
library(ggpmisc)
p <- ggplot(mpg, aes(factor(cyl), hwy, fill = factor(cyl))) +
stat_summary(geom = "col", fun.y = mean, width = 2/3) +
labs(x = "Number of cylinders", y = NULL, title = "Means") +
scale_fill_discrete(guide = FALSE)
data.tb <- tibble(x = 7, y = 44,
plot = list(p +
theme_bw(8)))
ggplot(mpg, aes(displ, hwy, colour = factor(cyl))) +
geom_plot(data = data.tb, aes(x, y, label = plot)) +
geom_point() +
labs(x = "Engine displacement (l)", y = "Fuel use efficiency (MPG)",
colour = "Engine cylindersn(number)") +
theme_bw()
add a comment |
'ggplot2' >= 3.0.0 makes possible new approaches for adding insets, as now tibble
objects containing lists as member columns can be passed as data. The objects in the list column can be even whole ggplots... The latest version of my package 'ggpmisc' provides geom_plot()
, geom_table()
and geom_grob()
, and also versions that use npc units instead of native data units for locating the insets. These geoms can add multiple insets per call and obey faceting, which annotation_custom()
does not. I copy the example from the help page, which adds an inset with a zoom-in detail of the main plot as an inset.
library(tibble)
library(ggpmisc)
p <-
ggplot(data = mtcars, mapping = aes(wt, mpg)) +
geom_point()
df <- tibble(x = 0.01, y = 0.01,
plot = list(p +
coord_cartesian(xlim = c(3, 4),
ylim = c(13, 16)) +
labs(x = NULL, y = NULL) +
theme_bw(10)))
p +
expand_limits(x = 0, y = 0) +
geom_plot_npc(data = df, aes(npcx = x, npcy = y, label = plot))
Or a barplot as inset, taken from the package vignette.
library(tibble)
library(ggpmisc)
p <- ggplot(mpg, aes(factor(cyl), hwy, fill = factor(cyl))) +
stat_summary(geom = "col", fun.y = mean, width = 2/3) +
labs(x = "Number of cylinders", y = NULL, title = "Means") +
scale_fill_discrete(guide = FALSE)
data.tb <- tibble(x = 7, y = 44,
plot = list(p +
theme_bw(8)))
ggplot(mpg, aes(displ, hwy, colour = factor(cyl))) +
geom_plot(data = data.tb, aes(x, y, label = plot)) +
geom_point() +
labs(x = "Engine displacement (l)", y = "Fuel use efficiency (MPG)",
colour = "Engine cylindersn(number)") +
theme_bw()
'ggplot2' >= 3.0.0 makes possible new approaches for adding insets, as now tibble
objects containing lists as member columns can be passed as data. The objects in the list column can be even whole ggplots... The latest version of my package 'ggpmisc' provides geom_plot()
, geom_table()
and geom_grob()
, and also versions that use npc units instead of native data units for locating the insets. These geoms can add multiple insets per call and obey faceting, which annotation_custom()
does not. I copy the example from the help page, which adds an inset with a zoom-in detail of the main plot as an inset.
library(tibble)
library(ggpmisc)
p <-
ggplot(data = mtcars, mapping = aes(wt, mpg)) +
geom_point()
df <- tibble(x = 0.01, y = 0.01,
plot = list(p +
coord_cartesian(xlim = c(3, 4),
ylim = c(13, 16)) +
labs(x = NULL, y = NULL) +
theme_bw(10)))
p +
expand_limits(x = 0, y = 0) +
geom_plot_npc(data = df, aes(npcx = x, npcy = y, label = plot))
Or a barplot as inset, taken from the package vignette.
library(tibble)
library(ggpmisc)
p <- ggplot(mpg, aes(factor(cyl), hwy, fill = factor(cyl))) +
stat_summary(geom = "col", fun.y = mean, width = 2/3) +
labs(x = "Number of cylinders", y = NULL, title = "Means") +
scale_fill_discrete(guide = FALSE)
data.tb <- tibble(x = 7, y = 44,
plot = list(p +
theme_bw(8)))
ggplot(mpg, aes(displ, hwy, colour = factor(cyl))) +
geom_plot(data = data.tb, aes(x, y, label = plot)) +
geom_point() +
labs(x = "Engine displacement (l)", y = "Fuel use efficiency (MPG)",
colour = "Engine cylindersn(number)") +
theme_bw()
answered Apr 11 at 14:45
Pedro AphaloPedro Aphalo
1,6311114
1,6311114
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5219671%2fit-is-possible-to-create-inset-graphs%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
This post on the Learning R blog goes over how to plot inside a plot. The blog has a lot of other great posts on ggplot2.
– Erik Shilts
Mar 7 '11 at 15:03