英文:
How to overlay xy coordinates onto an image
问题
I can help with that. You're looking to create a heatmap visualization of XY coordinates on top of the body image. You've provided a dataset with XY coordinates, and you'd like to use Python, R, or JavaScript for this task. Here's the translated content:
我可以帮助您。您想要在身体图像上创建一个热度图可视化,以显示XY坐标。您已经提供了一个包含XY坐标的数据集,您想要使用Python、R或JavaScript来完成这项任务。以下是翻译好的内容。
英文:
I have a dataset (n=256) with xy coordinates (>10) that have been exported from an online survey that map onto an image of a body. Essentially, participants (n=256) were asked to indicate on the body map where they experience pain (a max of 10 xy pairs).
Now I'm trying to work out how to map these coordinates on top of the image (597 × 597 - image below) to give a "heat map" visual.
I have tried some online tutorials but they are all limited to overlaying coordinates onto a google maps image.
A subset of my data looks like this:
ID x1 y1 x2 y2 x3 y3 x4 y4 x5 y5 x6 y6 x7 y7 x8 y8 x9 y9 x10 y10
1 467 77 135 121 104 265 135 170 155 481 441 406 488 221 462 279 541 300 390 299
2 495 464 476 520 486 488 129 436 130 468 156 262
3 133 274 147 259 117 256
4 132 140 451 89 493 101 123 92 157 89 123 240 155 243 440 296 509 297
5 156 495 490 499 442 495 121 502 158 269
6 123 244 151 256 158 151 175 189 434 419 472 496 431 353 394 189 414 149
7 134 100 135 127 112 163
8 95 304 509 301 118 271 149 269
9 136 247 148 148 165 194 153 506 153 320 127 200 132 123 439 533
10 130 135 177 324 162 294 141 255
11 146 249 490 307 507 165 411 167 397 239 490 406 444 400 427 300 204 284 54 277
12 440 415 482 415 535 336 454 530 439 527
13 105 497 177 162 186 195 481 492 420 149 421 191 165 272 158 314 435 283 435 311
14 153 254 100 382 145 76 145 133 197 230 437 195 452 302 466 146
15 379 331 553 328 218 292 54 296 52 333 227 334 385 299 545 301 443 416
16 135 113 467 87 131 251 149 262 222 323 209 286 151 139 133 172
17 121 110 139 109 107 143 172 145 451 137 480 136 140 162 123 165 123 131 147 135
18 131 129 172 152 105 157 151 250 122 252 168 288 110 298 487 136 451 137
19 448 406 500 153 437 158 472 93 459 307 446 303 431 281 422 293 489 500 452 495
20 145 252 468 143 429 161 506 166 175 145 131 145 466 69 138 74
21 480 289 116 279 124 271 458 285 472 148 124 148 148 141 157 265
22 84 313 427 304 503 309 182 309 510 172 412 168 126 232 128 133 493 414 444 414
23 452 110 431 163 440 310 461 316 145 278 137 73 459 90 144 118 159 145 145 313
24 118 277 153 276 130 125 126 84 139 525 458 83 444 507 485 504 441 284 492 274
25 503 287 389 296 546 293 426 287 488 404 447 498 491 497 135 177 500 151 433 151
26 476 397 448 400 109 142 83 228 126 527
27 150 499 123 503 500 219 432 222 511 177 417 182 451 411 491 411 452 532 489 539
28 441 410 485 408 208 273 63 273 177 158
29 163 410 148 409 435 415 444 404
30 446 403 485 407 480 532 447 527 561 341 501 301 113 260 374 336
31 441 407 153 409 133 255
32
33 148 133 492 416 441 412 115 264 498 449 477 443 451 423 495 356 178 150 99 276
34 499 454 497 468 494 479 495 491 144 535 148 524 122 519 134 128 151 257 124 259
35 454 192 457 288 489 503 558 288 323 294 141 272 133 205 131 168 131 508 141 135
Ideally, I'd like to use python, R, or js so I can understand it and use in my script (currently using R).
Massive thanks in advance
Edit
Here is the csv bodymap
答案1
得分: 2
这是实际数据吗?还是假数据或示例数据?我在将数据点与预期的身体部位对齐方面遇到了困难,例如,我相当确定很多人有腰痛,所以"大腿"的集群是否应该更高一些?
以下是一种潜在的方法:
加载示例数据:
library(tidyverse)
library(grid)
library(png)
df <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35),
x1 = c(467, 495, 133, 132, 156,
123, 134, 95, 136, 130, 146, 440, 105, 153, 379, 135, 121, 131,
448, 145, 480, 84, 452, 118, 503, 476, 150, 441, 163, 446, 441,
NA, 148, 499, 454),
y1 = c(77, 464, 274, 140, 495, 244, 100,
304, 247, 135, 249, 415, 497, 254, 331, 113, 110, 129, 406, 252,
289, 313, 110, 277, 287, 397, 499, 410, 410, 403, 407, NA, 133,
454, 192),
x2 = c(135, 476, 147, 451, 490, 151, 135, 509, 148,
177, 490, 482, 177, 100, 553, 467, 139, 172, 500, 468, 116, 427,
431, 153, 389, 448, 123, 485, 148, 485, 153, NA, 492, 497, 457),
y2 = c(121, 520, 259, 89, 499, 256, 127, 301, 148, 324, 307,
415, 162, 382, 328, 87, 109, 152, 153, 143, 279, 304, 163, 276,
296, 400, 503, 408, 409, 407, 409, NA, 416, 468, 288),
x3 = c(104,
486, 117, 493, 442, 158, 112, 118, 165, 162, 507, 535, 186, 145,
218, 131, 107, 105, 437, 429, 124, 503, 440, 130, 546, 109, 500,
208, 435, 480, 133, NA, 441, 494, 489),
y3 = c(265, 488, 256,
101, 495, 151, 163, 271, 194, 294, 165, 336, 195, 76, 292, 251,
143, 157, 158, 161, 271, 309, 310, 125, 293, 142, 219, 273, 415,
532, 255, NA, 412, 479, 503),
x4 = c(135, 129, NA, 123, 121,
175, NA, 149, 153, 141, 411, 454, 481, 145, 54, 149, 172, 151,
472, 506, 458, 182, 461, 126, 426, 83, 432, 63, 444, 447, NA,
NA, 115, 495, 558),
y4 = c(170, 436, NA, 92, 502, 189, NA, 269,
506, 255, 167, 530, 492, 133, 296, 262, 145, 250, 93, 166, 285,
309, 316, 84, 287, 228, 222, 273, 404, 527, NA, NA, 264, 491,
288),
x5 = c(155, 130, NA, 157, 158, 434, NA, NA, 153, NA, 397,
439, 420, 197, 52, 222, 451, 122, 459, 175, 472, 510, 145, 139,
488, 126, 511, 177, NA, 561, NA, NA, 498, 144, 323),
y5 = c(481,
468, NA, 89, 269, 419, NA, NA, 320, NA, 239, 527, 149, 230, 333,
323, 137, 252, 307, 145, 148, 172, 278, 525, 404, 527, 177, 158,
NA, 341, NA, NA, 449, 535, 294),
x6 = c(441, 156, NA, 123, NA,
472, NA, NA, 127, NA, 490, NA, 421, 437, 227, 209, 480, 168,
446, 131, 124, 412, 137, 458, 447, NA, 417, NA, NA, 501, NA,
NA, 477, 148, 141),
y6 = c(406, 262, NA, 240, NA, 496, NA, NA,
200, NA, 406, NA, 191, 195, 334, 286, 136, 288, 303, 145, 148
<details>
<summary>英文:</summary>
Is this real data? Or fake/example data? I'm having trouble getting the data points to 'line up' with the expected body parts e.g. pretty sure lots of people have lower back pain, should the 'thigh' cluster be higher up?
Here is one potential approach:
Load the example data:
``` r
library(tidyverse)
library(grid)
library(png)
df <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35),
x1 = c(467, 495, 133, 132, 156,
123, 134, 95, 136, 130, 146, 440, 105, 153, 379, 135, 121, 131,
448, 145, 480, 84, 452, 118, 503, 476, 150, 441, 163, 446, 441,
NA, 148, 499, 454),
y1 = c(77, 464, 274, 140, 495, 244, 100,
304, 247, 135, 249, 415, 497, 254, 331, 113, 110, 129, 406, 252,
289, 313, 110, 277, 287, 397, 499, 410, 410, 403, 407, NA, 133,
454, 192),
x2 = c(135, 476, 147, 451, 490, 151, 135, 509, 148,
177, 490, 482, 177, 100, 553, 467, 139, 172, 500, 468, 116, 427,
431, 153, 389, 448, 123, 485, 148, 485, 153, NA, 492, 497, 457),
y2 = c(121, 520, 259, 89, 499, 256, 127, 301, 148, 324, 307,
415, 162, 382, 328, 87, 109, 152, 153, 143, 279, 304, 163, 276,
296, 400, 503, 408, 409, 407, 409, NA, 416, 468, 288),
x3 = c(104,
486, 117, 493, 442, 158, 112, 118, 165, 162, 507, 535, 186, 145,
218, 131, 107, 105, 437, 429, 124, 503, 440, 130, 546, 109, 500,
208, 435, 480, 133, NA, 441, 494, 489),
y3 = c(265, 488, 256,
101, 495, 151, 163, 271, 194, 294, 165, 336, 195, 76, 292, 251,
143, 157, 158, 161, 271, 309, 310, 125, 293, 142, 219, 273, 415,
532, 255, NA, 412, 479, 503),
x4 = c(135, 129, NA, 123, 121,
175, NA, 149, 153, 141, 411, 454, 481, 145, 54, 149, 172, 151,
472, 506, 458, 182, 461, 126, 426, 83, 432, 63, 444, 447, NA,
NA, 115, 495, 558),
y4 = c(170, 436, NA, 92, 502, 189, NA, 269,
506, 255, 167, 530, 492, 133, 296, 262, 145, 250, 93, 166, 285,
309, 316, 84, 287, 228, 222, 273, 404, 527, NA, NA, 264, 491,
288),
x5 = c(155, 130, NA, 157, 158, 434, NA, NA, 153, NA, 397,
439, 420, 197, 52, 222, 451, 122, 459, 175, 472, 510, 145, 139,
488, 126, 511, 177, NA, 561, NA, NA, 498, 144, 323),
y5 = c(481,
468, NA, 89, 269, 419, NA, NA, 320, NA, 239, 527, 149, 230, 333,
323, 137, 252, 307, 145, 148, 172, 278, 525, 404, 527, 177, 158,
NA, 341, NA, NA, 449, 535, 294),
x6 = c(441, 156, NA, 123, NA,
472, NA, NA, 127, NA, 490, NA, 421, 437, 227, 209, 480, 168,
446, 131, 124, 412, 137, 458, 447, NA, 417, NA, NA, 501, NA,
NA, 477, 148, 141),
y6 = c(406, 262, NA, 240, NA, 496, NA, NA,
200, NA, 406, NA, 191, 195, 334, 286, 136, 288, 303, 145, 148,
168, 73, 83, 498, NA, 182, NA, NA, 301, NA, NA, 443, 524, 272),
x7 = c(488, NA, NA, 155, NA, 431, NA, NA, 132, NA, 444, NA,
165, 452, 385, 151, 140, 110, 431, 466, 148, 126, 459, 444, 491,
NA, 451, NA, NA, 113, NA, NA, 451, 122, 133),
y7 = c(221, NA,
NA, 243, NA, 353, NA, NA, 123, NA, 400, NA, 272, 302, 299, 139,
162, 298, 281, 69, 141, 232, 90, 507, 497, NA, 411, NA, NA, 260,
NA, NA, 423, 519, 205),
x8 = c(462, NA, NA, 440, NA, 394, NA,
NA, 439, NA, 427, NA, 158, 466, 545, 133, 123, 487, 422, 138,
157, 128, 144, 485, 135, NA, 491, NA, NA, 374, NA, NA, 495, 134,
131),
y8 = c(279, NA, NA, 296, NA, 189, NA, NA, 533, NA, 300,
NA, 314, 146, 301, 172, 165, 136, 293, 74, 265, 133, 118, 504,
177, NA, 411, NA, NA, 336, NA, NA, 356, 128, 168),
x9 = c(541,
NA, NA, 509, NA, 414, NA, NA, NA, NA, 204, NA, 435, NA, 443,
NA, 123, 451, 489, NA, NA, 493, 159, 441, 500, NA, 452, NA, NA,
NA, NA, NA, 178, 151, 131),
y9 = c(300, NA, NA, 297, NA, 149,
NA, NA, NA, NA, 284, NA, 283, NA, 416, NA, 131, 137, 500, NA,
NA, 414, 145, 284, 151, NA, 532, NA, NA, NA, NA, NA, 150, 257,
508),
x10 = c(390, NA, NA, NA, NA, NA, NA, NA, NA, NA, 54, NA,
435, NA, NA, NA, 147, NA, 452, NA, NA, 444, 145, 492, 433, NA,
489, NA, NA, NA, NA, NA, 99, 124, 141),
y10 = c(299, NA, NA,
NA, NA, NA, NA, NA, NA, NA, 277, NA, 311, NA, NA, NA, 135, NA,
495, NA, NA, 414, 313, 274, 151, NA, 539, NA, NA, NA, NA, NA,
276, 259, 135)),
row.names = c(NA, -35L), spec = structure(list(
cols = list(ID = structure(list(), class = c("collector_double",
"collector")),
x1 = structure(list(), class = c("collector_double",
"collector")),
y1 = structure(list(), class = c("collector_double",
"collector")),
x2 = structure(list(), class = c("collector_double",
"collector")),
y2 = structure(list(), class = c("collector_double",
"collector")),
x3 = structure(list(), class = c("collector_double",
"collector")),
y3 = structure(list(), class = c("collector_double",
"collector")),
x4 = structure(list(), class = c("collector_double",
"collector")),
y4 = structure(list(), class = c("collector_double",
"collector")),
x5 = structure(list(), class = c("collector_double",
"collector")),
y5 = structure(list(), class = c("collector_double",
"collector")),
x6 = structure(list(), class = c("collector_double",
"collector")),
y6 = structure(list(), class = c("collector_double",
"collector")),
x7 = structure(list(), class = c("collector_double",
"collector")),
y7 = structure(list(), class = c("collector_double",
"collector")),
x8 = structure(list(), class = c("collector_double",
"collector")),
y8 = structure(list(), class = c("collector_double",
"collector")),
x9 = structure(list(), class = c("collector_double",
"collector")),
y9 = structure(list(), class = c("collector_double",
"collector")),
x10 = structure(list(), class = c("collector_double",
"collector")),
y10 = structure(list(), class = c("collector_double",
"collector"))),
default = structure(list(), class = c("collector_guess", "collector")), delim = "\t"), class = "col_spec"),
problems = "<pointer: 0x7fb2892c4200>",
class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"))
Load the image, generate the plot, and combine using grid:
img <- readPNG("~/Desktop/l78U8.png")
#> Warning in readPNG("~/Desktop/l78U8.png"): libpng warning: iCCP: extra
#> compressed data
g1 <- df %>%
pivot_longer(-ID, names_pattern = "([a-z]+)(\\d+)",
names_to = c("coord", "num")) %>%
pivot_wider(id_cols = c(ID, num), names_from = coord, values_from = value) %>%
ggplot(aes(x = x, y = y, fill = after_stat(density))) +
geom_hex() +
scale_fill_viridis_c(option = "C") +
theme_void() +
theme(legend.position = "none") +
coord_equal(expand = TRUE)
grid.draw(gList(rasterGrob(img, width = unit(0.8,"npc"), height = unit(1.2, "npc")),
ggplotGrob(g1)))
#> Warning: Removed 89 rows containing non-finite values (`stat_binhex()`).
<!-- -->
<sup>Created on 2023-05-18 with reprex v2.0.2</sup>
Edit
Changing the alpha makes the plot look a bit nicer (i.e. geom_hex(alpha = 0.75)
):
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论