I am trying to insert an image at the top of an already existing ggplot
object. Below is an example of my end goal, created using an image processor.
...and here is some code that replicates the ggplot side of the arrangement.
library(tidyverse)
proportion<-data.frame(group=c(rep("A",10),
rep("B",10),
rep("C",10)),
num=c(rnorm(20,mean=0.45,sd=0.05),
rnorm(20,mean=0.55,sd=0.05),
rnorm(20,mean=0.5,sd=0.05)))
proportion %>%
ggplot(aes(x=num,y=group)) +
geom_boxplot(width=0.5)+
coord_cartesian(xlim=c(0,1))+
labs(x="measurement (as percent of total length)",y="group")+
geom_vline(xintercept=c(0,1))
The graph is supposed to represent the location of something on a fish's body as a percentage of body length and placing a silhouette immediately above the y-axis gives readers a more intuitive idea of what the graph is measuring. The xmin and xmax of the silhouette need to be aligned with c(0,1) on the x-axis of the graph in order to get the comparison across.
This data is supposed to be for a data report in an RMarkdown file knitted to .html, so it is not possible to simply export the ggplot from R and editing it in an image processor. I am having trouble figuring out the best way to achieve this in R. I have tried using the cowplot
and magick
packages, but have found it is difficult to place an image on the graph if the y-axis is a discrete variable. I think this might be achievable through the use of gridExtra
and calling an additional viewport, but I do not know how to get the image to properly line up with the graph below. Does anyone know how this can be achieved?
A sure fire way to do this is load your fish shape into a raster, convert to polygons, then normalise the co-ordinates so that they reach exactly between 0 and 1 on the x axis. You can then plot the fish as a polygon in ggplot and stitch the two plots together with patchwork
- this will automatically align the fish and proportions. A patchwork plot will work nicely with R Markdown too.
library(ggplot2)
library(patchwork)
p1 <- ggplot(fish, aes(X, Y)) +
geom_polygon(fill = "steelblue", alpha = 0.5) +
geom_vline(xintercept = c(0, 1)) +
scale_x_continuous(expand = c(0, 0)) +
theme_void()
p2 <- proportion %>%
ggplot(aes(x = num,y = group)) +
geom_boxplot(width = 0.5, fill = "lightblue", alpha = 0.5) +
coord_cartesian(xlim = c(0, 1)) +
scale_x_continuous(expand = c(0, 0)) +
labs(x = "measurement (as percent of total length)", y = "group") +
geom_vline(xintercept = c(0, 1)) +
theme_classic(base_size = 16) +
theme(axis.line.y = element_blank())
p1 / p2 + plot_layout(heights = 1:2) & theme(plot.margin = margin(0, 20, 0, 0))
Fish shape as xy co-ordinates
fish <- structure(list(X = c(286, 289, 289, 290, 290, 291, 291, 290,
290, 291, 291, 295, 295, 297, 297, 298, 298, 299, 299, 300, 300,
301, 301, 302, 302, 303, 303, 304, 304, 305, 305, 306, 306, 307,
307, 308, 308, 309, 309, 310, 310, 311, 311, 312, 312, 313, 313,
312, 312, 313, 313, 316, 316, 318, 318, 319, 319, 320, 320, 321,
321, 322, 322, 323, 323, 324, 324, 325, 325, 327, 327, 328, 328,
329, 329, 330, 330, 331, 331, 332, 332, 333, 333, 334, 334, 335,
335, 336, 336, 335, 335, 333, 333, 330, 330, 326, 326, 323, 323,
320, 320, 316, 316, 322, 322, 328, 328, 335, 335, 340, 340, 347,
347, 353, 353, 359, 359, 366, 366, 372, 372, 379, 379, 387, 387,
393, 393, 402, 402, 409, 409, 417, 417, 421, 421, 427, 427, 432,
432, 436, 436, 440, 440, 444, 444, 450, 450, 452, 452, 456, 456,
458, 458, 459, 459, 460, 460, 461, 461, 462, 462, 461, 461, 460,
460, 459, 459, 457, 457, 454, 454, 451, 451, 453, 453, 481, 481,
488, 488, 492, 492, 494, 494, 497, 497, 498, 498, 500, 500, 501,
501, 503, 503, 505, 505, 506, 506, 508, 508, 509, 509, 510, 510,
512, 512, 514, 514, 516, 516, 518, 518, 520, 520, 521, 521, 523,
523, 525, 525, 528, 528, 530, 530, 532, 532, 534, 534, 536, 536,
539, 539, 541, 541, 544, 544, 546, 546, 549, 549, 552, 552, 555,
555, 558, 558, 574, 574, 575, 575, 574, 574, 575, 575, 576, 576,
575, 575, 576, 576, 575, 575, 574, 574, 575, 575, 574, 574, 573,
573, 572, 572, 571, 571, 570, 570, 569, 569, 568, 568, 567, 567,
568, 568, 569, 569, 570, 570, 571, 571, 572, 572, 573, 573, 574,
574, 575, 575, 576, 576, 577, 577, 578, 578, 579, 579, 580, 580,
581, 581, 576, 576, 571, 571, 566, 566, 555, 555, 550, 550, 545,
545, 541, 541, 537, 537, 534, 534, 530, 530, 527, 527, 524, 524,
521, 521, 519, 519, 516, 516, 513, 513, 510, 510, 508, 508, 505,
505, 502, 502, 498, 498, 495, 495, 491, 491, 486, 486, 481, 481,
465, 465, 457, 457, 451, 451, 446, 446, 442, 442, 443, 443, 446,
446, 454, 454, 456, 456, 457, 457, 456, 456, 455, 455, 454, 454,
453, 453, 452, 452, 451, 451, 450, 450, 449, 449, 448, 448, 447,
447, 446, 446, 443, 443, 439, 439, 437, 437, 434, 434, 432, 432,
430, 430, 428, 428, 425, 425, 423, 423, 421, 421, 419, 419, 417,
417, 415, 415, 413, 413, 411, 411, 409, 409, 407, 407, 405, 405,
403, 403, 401, 401, 400, 400, 398, 398, 396, 396, 394, 394, 392,
392, 391, 391, 389, 389, 387, 387, 386, 386, 384, 384, 382, 382,
381, 381, 379, 379, 377, 377, 373, 373, 348, 348, 340, 340, 329,
329, 322, 322, 315, 315, 309, 309, 304, 304, 302, 302, 303, 303,
304, 304, 305, 305, 306, 306, 307, 307, 308, 308, 309, 309, 308,
308, 300, 300, 299, 299, 297, 297, 296, 296, 294, 294, 293, 293,
292, 292, 290, 290, 289, 289, 288, 288, 287, 287, 286, 286, 285,
285, 284, 284, 283, 283, 281, 281, 279, 279, 278, 278, 277, 277,
276, 276, 275, 275, 273, 273, 272, 272, 271, 271, 270, 270, 266,
266, 265, 265, 263, 263, 262, 262, 261, 261, 260, 260, 259, 259,
258, 258, 257, 257, 256, 256, 255, 255, 253, 253, 251, 251, 240,
240, 233, 233, 207, 207, 199, 199, 190, 190, 181, 181, 174, 174,
166, 166, 160, 160, 154, 154, 153, 153, 152, 152, 151, 151, 147,
147, 144, 144, 142, 142, 141, 141, 140, 140, 139, 139, 138, 138,
137, 137, 136, 136, 135, 135, 134, 134, 133, 133, 132, 132, 131,
131, 130, 130, 129, 129, 128, 128, 127, 127, 126, 126, 125, 125,
124, 124, 123, 123, 122, 122, 121, 121, 120, 120, 119, 119, 115,
115, 111, 111, 108, 108, 104, 104, 100, 100, 96, 96, 92, 92,
88, 88, 84, 84, 80, 80, 76, 76, 72, 72, 68, 68, 65, 65, 60, 60,
56, 56, 52, 52, 48, 48, 44, 44, 39, 39, 35, 35, 31, 31, 28, 28,
24, 24, 21, 21, 18, 18, 16, 16, 13, 13, 11, 11, 9, 9, 8, 8, 6,
6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 13, 13, 11, 11,
9, 9, 6, 6, 4, 4, 3, 3, 2, 2, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
6, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 14, 14, 15, 15, 17, 17,
18, 18, 20, 20, 22, 22, 25, 25, 27, 27, 30, 30, 33, 33, 35, 35,
38, 38, 41, 41, 44, 44, 47, 47, 50, 50, 53, 53, 56, 56, 59, 59,
65, 65, 67, 67, 70, 70, 74, 74, 77, 77, 81, 81, 84, 84, 87, 87,
91, 91, 94, 94, 98, 98, 103, 103, 107, 107, 113, 113, 118, 118,
124, 124, 130, 130, 136, 136, 144, 144, 152, 152, 160, 160, 171,
171, 199, 199, 201, 201, 202, 202, 221, 221, 226, 226, 228, 228,
229, 229, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235,
235, 236, 236, 237, 237, 238, 238, 239, 239, 240, 240, 241, 241,
242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248,
248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254,
255, 255, 257, 257, 258, 258, 259, 259, 260, 260, 261, 261, 263,
263, 264, 264, 265, 265, 267, 267, 268, 268, 269, 269, 271, 271,
272, 272, 274, 274, 275, 275, 277, 277, 278, 278, 280, 280, 281,
281, 283, 283, 284, 284, 286, 286), Y = c(210, 210, 209, 209,
208, 208, 203, 203, 202, 202, 201, 201, 200, 200, 199, 199, 198,
198, 197, 197, 195, 195, 194, 194, 193, 193, 192, 192, 190, 190,
189, 189, 188, 188, 187, 187, 185, 185, 184, 184, 182, 182, 181,
181, 179, 179, 177, 177, 175, 175, 176, 176, 175, 175, 174, 174,
173, 173, 172, 172, 171, 171, 170, 170, 169, 169, 168, 168, 167,
167, 166, 166, 165, 165, 164, 164, 163, 163, 162, 162, 161, 161,
159, 159, 158, 158, 156, 156, 154, 154, 153, 153, 152, 152, 151,
151, 150, 150, 149, 149, 148, 148, 146, 146, 145, 145, 144, 144,
143, 143, 142, 142, 141, 141, 140, 140, 139, 139, 138, 138, 137,
137, 136, 136, 135, 135, 134, 134, 133, 133, 132, 132, 131, 131,
132, 132, 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138,
138, 137, 137, 136, 136, 135, 135, 134, 134, 133, 133, 132, 132,
130, 130, 129, 129, 128, 128, 127, 127, 126, 126, 125, 125, 124,
124, 123, 123, 124, 124, 125, 125, 126, 126, 127, 127, 128, 128,
129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135,
135, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141,
142, 142, 143, 143, 144, 144, 145, 145, 146, 146, 147, 147, 148,
148, 149, 149, 150, 150, 151, 151, 152, 152, 153, 153, 154, 154,
155, 155, 156, 156, 157, 157, 158, 158, 157, 157, 155, 155, 154,
154, 144, 144, 143, 143, 138, 138, 137, 137, 130, 130, 126, 126,
122, 122, 118, 118, 115, 115, 113, 113, 111, 111, 109, 109, 104,
104, 101, 101, 97, 97, 94, 94, 91, 91, 87, 87, 81, 81, 79, 79,
78, 78, 77, 77, 75, 75, 72, 72, 69, 69, 62, 62, 58, 58, 55, 55,
50, 50, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55,
56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63,
64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71,
72, 72, 73, 73, 72, 72, 71, 71, 70, 70, 69, 69, 67, 67, 66, 66,
65, 65, 64, 64, 63, 63, 56, 56, 44, 44, 35, 35, 30, 30, 26, 26,
24, 24, 21, 21, 19, 19, 18, 18, 16, 16, 15, 15, 14, 14, 13, 13,
14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21,
22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29,
30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37,
38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45,
46, 46, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41,
40, 40, 39, 39, 36, 36, 32, 32, 25, 25, 24, 24, 20, 20, 14, 14,
1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9,
9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 18, 18, 17, 17, 18,
18, 19, 19, 20, 20, 21, 21, 22, 22, 20, 20, 19, 19, 18, 18, 17,
17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 24, 24, 26, 26, 29,
29, 30, 30, 32, 32, 33, 33, 34, 34, 35, 35, 34, 34, 35, 35, 36,
36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 21, 21, 19,
19, 18, 18, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23,
23, 24, 24, 25, 25, 26, 26, 28, 28, 29, 29, 31, 31, 32, 32, 34,
34, 35, 35, 36, 36, 38, 38, 39, 39, 41, 41, 42, 42, 43, 43, 45,
45, 46, 46, 47, 47, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54,
54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62,
62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70,
70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78,
78, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86,
86, 87, 87, 91, 91, 92, 92, 93, 93, 94, 94, 95, 95, 96, 96, 97,
97, 98, 98, 99, 99, 105, 105, 106, 106, 107, 107, 108, 108, 109,
109, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116,
117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123,
123, 124, 124, 125, 125, 126, 126, 127, 127, 128, 128, 129, 129,
130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135, 136,
136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141, 142, 142,
143, 143, 144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149,
149, 150, 150, 151, 151, 152, 152, 153, 153, 154, 154, 155, 155,
156, 156, 157, 157, 158, 158, 157, 157, 158, 158, 159, 159, 160,
160, 161, 161, 162, 162, 163, 163, 164, 164, 165, 165, 166, 166,
167, 167, 168, 168, 169, 169, 170, 170, 171, 171, 172, 172, 173,
173, 174, 174, 175, 175, 176, 176, 177, 177, 178, 178, 179, 179,
180, 180, 181, 181, 182, 182, 183, 183, 184, 184, 185, 185, 186,
186, 187, 187, 188, 188, 189, 189, 190, 190, 191, 191, 192, 192,
193, 193, 194, 194, 195, 195, 196, 196, 197, 197, 198, 198, 199,
199, 200, 200, 201, 201, 202, 202, 203, 203, 204, 204, 205, 205,
206, 206, 207, 207, 208, 208, 209, 209, 210)),
row.names = 6:968, class = "data.frame")/581