Inserting an image to ggplot2
try ?annotation_custom
in ggplot2
example,
library(png)
library(grid)
img <- readPNG(system.file("img", "Rlogo.png", package="png"))
g <- rasterGrob(img, interpolate=TRUE)
qplot(1:10, 1:10, geom="blank") +
annotation_custom(g, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
geom_point()
How to add image to a ggplot
This will plot the image instead of a point
library("ggplot2")
library("ggimage")
d <- data.frame(x = 1:2,
y = 1:2,
image = c("https://nba-players.herokuapp.com/players/james/lebron",
"https://nba-players.herokuapp.com/players/james/lebron"))
ggplot(d, aes(x, y)) +
geom_image(aes(image=image), size=.2) +
scale_x_continuous(limits = c(0, 3)) +
scale_y_continuous(limits = c(0,3))
Insert Image/PNG ggplot2 - Cowplot
It's in the coordinates of the plot. The point that may be confusing you is that ggdraw()
is setting up a new coordinate system running from 0 to 1 in both x and y. If you want to draw an image in the plot coordinates, there's no need to use ggdraw()
. Just add draw_plot()
directly to the plot.
library(ggplot2)
library(cowplot)
theme_set(theme_bw())
p1 <- qplot(Sepal.Length, Sepal.Width, data = iris)
# ggdraw() sets up a new coordinate system running from 0 to 1. This
# allows you to place an image on top of the plot.
ggdraw(p1) +
draw_image("https://upload.wikimedia.org/wikipedia/en/7/77/EricCartman.png")
# if you want to draw the image into the plot, don't use ggdraw()
p1 + draw_image(
"https://upload.wikimedia.org/wikipedia/en/7/77/EricCartman.png",
x = 5, y = 2.5, width = 2, height = 1.5
)
Created on 2018-12-19 by the reprex package (v0.2.1)
ggplot adding image on top-right in two plots with different scales
We can automate the process of specifying the location and scales, so that you don't need to change the locations manually, as shown in the following example:
get.xy <- function(p) {
g_data <- ggplot_build(p)
data.frame(xmax = max(g_data$data[[1]]$x),
ymax = max(g_data$data[[1]]$y),
xmin = min(g_data$data[[1]]$x),
ymin = min(g_data$data[[1]]$y))
}
# this returns the dataframe with required x, y params for annotation_custom,
# ensuring the size and position of the image constant
get.params.df <- function(p0, p1, width, height) {
df0 <- cbind.data.frame(get.xy(p0), width=width, height=height)
df1 <- cbind.data.frame(get.xy(p1))
df1$width <- df0$width*(df1$xmax-df1$xmin)/(df0$xmax-df0$xmin)
df1$height <- df0$height*(df1$ymax-df1$ymin)/(df0$ymax-df0$ymin)
df <- rbind(df0, df1)
return(data.frame(xmin=df$xmax-df$width, xmax=df$xmax+df$width, ymin=df$ymax-df$height, ymax=df$ymax+df$height))
}
p0 <- plt(am0)
p1 <- plt(am1)
df <- get.params.df(p0, p1, width=10, height=10)
# adding image
library(gridExtra)
grid.arrange(
p0 + annotation_custom(rasterGrob(img), xmin=df[1,1],xmax=df[1,2], ymin=df[1,3], ymax=df[1,4]),
p1 + annotation_custom(rasterGrob(img), xmin=df[2,1],xmax=df[2,2], ymin=df[2,3], ymax=df[2,4])
)
If you want bigger image change the width height parameter only, everything else remains unchanged.
df <- get.params.df(p0, p1, width=25, height=25)
library(gridExtra)
grid.arrange(
p0 + annotation_custom(rasterGrob(img), xmin=df[1,1],xmax=df[1,2], ymin=df[1,3], ymax=df[1,4]),
p1 + annotation_custom(rasterGrob(img), xmin=df[2,1],xmax=df[2,2], ymin=df[2,3], ymax=df[2,4])
)
Inserting an image to ggplot outside the chart area
When faceting, annotation_custom
draws the annotation in all panels. Therefore, annotation-custom
might not be the best way to go. Here are two attempts using functions from the grid
package. Neither is entirely automatic, but you might be able to adapt one or the other to meet your needs. They set up a 2 X 2 grid, shown using the grid.show.layout()
command. In the first, the faceted plot fills the entire panel, and the top right viewport contains the logo. It just so happens that in your plot, there is clear space for the logo. Note how layout.pos.row
and layout.pos.col
give the rows and columns occupied by a viewport within the layout.
library(ggplot2)
library(png)
library(grid)
# Get the logo
img <- readPNG(system.file("img", "Rlogo.png", package="png"))
g <- rasterGrob(img)
# Set the size of the viewport to contain the logo
size = unit(2, "cm")
# Get the graph
d <- ggplot(diamonds, aes(carat, price)) +
xlim(0, 2) +
stat_binhex(na.rm = TRUE) +
labs(title = 'Title') +
theme(aspect.ratio = 1) +
facet_wrap(~ color, scales = "free_x")
# Set up the layout for grid
heights = unit.c(size, unit(1, "npc") - size)
widths = unit.c(unit(1, "npc") - size, size)
lo = grid.layout(2, 2, widths = widths, heights = heights)
# Show the layout
grid.show.layout(lo)
# Position the elements within the viewports
grid.newpage()
pushViewport(viewport(layout = lo))
# The plot
pushViewport(viewport(layout.pos.row=1:2, layout.pos.col = 1:2))
print(d, newpage=FALSE)
popViewport()
# The logo
pushViewport(viewport(layout.pos.row=1, layout.pos.col = 2))
print(grid.draw(g), newpage=FALSE)
popViewport()
popViewport()
# To save the object
g = grid.grab()
grid.newpage()
grid.draw(g)
The title does not entirely align with the logo. One fix is to remove the title from the ggplot, draw a separate textGrob that contains the title, then position the textGrob in the top left viewport beside the viewport that contains the logo.
# Get the logo
img <- readPNG(system.file("img", "Rlogo.png", package="png"))
g <- rasterGrob(img)
# Set the size of the viewport to contain the logo
size = unit(2, "cm")
# Get the graph
d <- ggplot(diamonds, aes(carat, price)) +
xlim(0, 2) +
stat_binhex(na.rm = TRUE) +
# labs(title = 'Title') +
theme(aspect.ratio = 1) +
facet_wrap(~ color, scales = "free_x")
# and the title
title = textGrob("Title", gp = gpar(face = "bold", cex = 2))
# Set up the layout for grid
heights = unit.c(size, unit(1, "npc") - size)
widths = unit.c(unit(1, "npc") - 1.5*size, size)
lo = grid.layout(2, 2, widths = widths, heights = heights)
# Show the layout
grid.show.layout(lo)
# Position the elements within the viewports
grid.newpage()
pushViewport(viewport(layout = lo))
# The plot
pushViewport(viewport(layout.pos.row=2, layout.pos.col = 1:2))
print(d, newpage=FALSE)
popViewport()
# The logo
pushViewport(viewport(layout.pos.row=1, layout.pos.col = 2))
print(grid.draw(g), newpage=FALSE)
popViewport()
# The title
pushViewport(viewport(layout.pos.row=1, layout.pos.col = 1))
print(grid.draw(title), newpage=FALSE)
popViewport()
popViewport()
# To save the object
g = grid.grab()
grid.newpage()
grid.draw(g)
Inserting an image to a bar chart in ggplot
One option is to use ggimage
. Source: https://guangchuangyu.github.io/pkgdocs/ggimage.html. Try this:
library(ggplot2)
library(ggimage)
library(dplyr)
set.seed(1234)
img <- list.files(system.file("extdata", package="ggimage"),
pattern="png", full.names=TRUE)
df = data.frame(
group = c('a', 'b', 'c'),
value = 1:3,
image = sample(img, size=3, replace = TRUE)
) %>%
mutate(value1 = .5 * value)
ggplot(df, aes(group, value)) +
geom_col() +
geom_image(aes(image=image, y = value1), size=.2)
Created on 2020-03-19 by the reprex package (v0.3.0)
How to insert pictures into each individual bar in a ggplot graph
You didn't provide a reprex, so I need to make something up. I would probably do it like this.
library(tidyverse)
library(ggtextures)
library(magick)
#> Linking to ImageMagick 6.9.9.39
#> Enabled features: cairo, fontconfig, freetype, lcms, pango, rsvg, webp
#> Disabled features: fftw, ghostscript, x11
data <- tibble(
count = c(5, 6, 6, 4, 2, 3),
animal = c("giraffe", "elephant", "horse", "bird", "turtle", "dog"),
image = list(
image_read_svg("http://steveharoz.com/research/isotype/icons/giraffe.svg"),
image_read_svg("http://steveharoz.com/research/isotype/icons/elephant.svg"),
image_read_svg("http://steveharoz.com/research/isotype/icons/horse.svg"),
image_read_svg("http://steveharoz.com/research/isotype/icons/bird.svg"),
image_read_svg("http://steveharoz.com/research/isotype/icons/turtle.svg"),
image_read_svg("http://steveharoz.com/research/isotype/icons/dog.svg")
)
)
ggplot(data, aes(animal, count, fill = animal, image = image)) +
geom_isotype_col(
img_height = grid::unit(1, "null"), img_width = NULL,
ncol = 1, nrow = 1, hjust = 1, vjust = 0.5
) +
coord_flip() +
guides(fill = "none") +
theme_minimal()
Created on 2019-11-03 by the reprex package (v0.3.0)
Related Topics
How to Export Multiple Data.Frame to Multiple Excel Worksheets
Standard Evaluation in Dplyr: Summarise a Variable Given as a Character String
Intelligent Point Label Placement in R
How to Convert Long to Wide Format With Counts
Sum Values in a Rolling/Sliding Window
Usage of '...' (Three-Dots or Dot-Dot-Dot) in Functions
Pass Column Name in Data.Table Using Variable
Editing Legend (Text) Labels in Ggplot
How to Display the Frequency At the Top of Each Factor in a Barplot in R
Rolling Mean (Moving Average) by Group/Id With Dplyr
Trimming a Huge (3.5 Gb) CSV File to Read into R
Make a Group_Indices Based on Several Columns
How to Change the Default Time Zone in R