فهرست مطالب
Toggleنحوه ساخت Heatmaps در ggplot
نقشههای حرارتی (Heatmaps) یک روش رایج برای نمایش دادهها هستند. در این پست وبلاگ، به شما نشان خواهیم داد که چگونه با استفاده از ggplot نقشههای حرارتی خود را بسازید. در این فرآیند، کمی در مورد کار با بسته {sf}، به ویژه تابع st_make_grid() برای ایجاد یک شبکه، تابع st_intersection() برای چسباندن مرزهای جغرافیایی خود به شبکهای که ایجاد میکنید، و تابع st_join() برای انجام اتصالات مکانی، یاد خواهید گرفت.
نقشه حرارتی (Heatmas) چیست؟
قبل از یادگیری نحوه ساخت نقشه حرارتی، بیایید در مورد چیستی نقشه حرارتی صحبت کنیم. نقشههای حرارتی ممکن است رایج باشند، اما یک تعریف واحد از نقشه حرارتی کمتر رایج است. آموزشهای مربوط به ساخت نقشههای حرارتی را در ggplot جستجو کنید و آموزشهایی برای استفاده از تابع geom_tile() برای ساخت نقشههای حرارتی مانند این دریافت خواهید کرد:
نقشه حرارتی موارد سرخک در ایالات متحده قبل و بعد از در دسترس قرار گرفتن واکسنها (منبع: گالری نمودار R)
انواع مختلفی از نقشههای حرارتی وجود دارد که در طبیعت خواهید دید. به عنوان مثال، این نقشه از واشنگتن پست، کل بارندگی در شبه جزیره کره را در یک دوره بارانی خاص در سال 2022 نشان میدهد.
نقشه میزان بارندگی در کره در ماههای جولای و آگوست ۲۰۲۲
یا این نقشه از توبیاس استادلر که مکان روستاهای سوئیس با جمعیت بیش از ۱۰۰۰۰ نفر را نشان میدهد.
نقشهای که مکان روستاهای سوئیس با جمعیت بیش از ۱۰۰۰۰ نفر را نشان میدهد
کاری که همه نقشههای حرارتی انجام میدهند این است که برخی پدیدهها و نتایج را در نوعی شبکه قرار میدهند:
- برای نمودار موارد سرخک، این شامل ایجاد یک مربع برای هر سال و ایالت است.
- برای نقشه بارش کره، این به معنای گرفتن دادههای ایستگاههای اندازهگیری باران و گروهبندی آنها برای ایجاد رنگهای هموار شدهای است که روی نقشه میبینید.
- برای نقشه روستاهای سوئیس توبیاس استادلر، این به معنای ایجاد یک شبکه از سوئیس، قرار دادن روستاها در یکی از سلولهای شبکه و سپس شمارش تعداد روستاها در هر سلول است.
پس از ایجاد شبکهها، هر سه این تجسمها از رنگ برای نشان دادن تراکم برخی از نتایج (موارد سرخک، بارندگی، تعداد روستاهای با جمعیت بیش از ۱۰ هزار نفر) استفاده میکنند. با توجه به این نکته، بیایید به سراغ ساخت نقشه حرارتی خودمان برویم.
نقشه حرارتی خود را ایجاد کنید
ما قصد داریم یک نقشه حرارتی ایجاد کنیم که موقعیت گوشههای بهبود یافته در پورتلند را نشان دهد. اینها گوشههایی هستند که دارای رمپ هستند که آنها را برای افراد دارای صندلی چرخدار، افرادی که کالسکه حمل میکنند و غیره قابل دسترسی میکند.
وارد کردن دادهها
برای شروع نقشه، چندین بسته را بارگذاری خواهیم کرد: {tidvyerse} برای پردازش دادههای عمومی و نقشهبرداری با ggplot، {sf} برای کار با دادههای جغرافیایی و {scales} برای ایجاد مقادیر با قالببندی زیبا.
library(tidyverse) library(sf) library(scales)
در مرحله بعد، دادههای خود را وارد خواهیم کرد. ما با وارد کردن یک فایل geojson حاوی موقعیت مکانی تمام گوشههای پورتلند شروع میکنیم.
improved_corners |> read_sf( "https://raw.githubusercontent.com/rfortherestofus/mapping-with-r-v2/refs/heads/main/data/improved_corners.geojson" )
میتوانیم به قاب داده improved_corners که ایجاد کردهایم نگاه کنیم و ببینیم که از یک متغیر id (objectid)، یک متغیر ramp_style (که یا Improved است یا Unimproved) و یک ستون geometry که شامل موقعیت هر گوشه است، تشکیل شده است:
#> Simple feature collection with 38492 features and 2 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: -122.8301 ymin: 45.43282 xmax: -122.4619 ymax: 45.63909 #> Geodetic CRS: WGS 84 #> # A tibble: 38,492 × 3 #> objectid ramp_style geometry #> <int> <chr> <POINT [°]> #> 1 1 Unimproved (-122.6607 45.6012) #> 2 2 Unimproved (-122.6606 45.60167) #> 3 3 Unimproved (-122.6605 45.60117) #> 4 4 Unimproved (-122.6604 45.60163) #> 5 5 Unimproved (-122.6603 45.60056) #> 6 6 Unimproved (-122.6603 45.60072) #> 7 7 Unimproved (-122.6602 45.60079) #> 8 8 Unimproved (-122.6551 45.59177) #> 9 9 Unimproved (-122.6546 45.59212) #> 10 10 Unimproved (-122.6538 45.59125) #> # ℹ 38,482 more rows
ما همچنین یک فایل geojson که حاوی مرزهای شهر پورتلند است را وارد خواهیم کرد.
portland_boundaries |>
read_sf(
"https://raw.githubusercontent.com/rfortherestofus/mapping-with-r-v2/refs/heads/main/data/portland_boundaries.geojson"
)
portland_boundaries |>
ggplot() +
geom_sf() +
theme_void()

ایجاد یک نقشه شبکهای
portland_grid |>
portland_boundaries |>
st_make_grid()
ggplot() +
geom_sf(data = portland_boundaries) +
geom_sf(
data = portland_grid,
alpha = 0.5
) +
theme_void()

portland_grid |>
portland_boundaries |>
st_make_grid(n = c(100, 100))

برش مرزهای شهر به نقشه شبکه
portland_grid_map |>
st_intersection(
portland_boundaries,
portland_grid
) |>
st_make_valid() |>
mutate(grid_id = row_number()) |>
select(grid_id)
portland_grid_map |>
ggplot() +
geom_sf() +
theme_void()

دادههای corner را با نقشه شبکهای به هم متصل کنید
improved_corners_grid |>
st_join(
portland_grid_map,
improved_corners
)
اگر به improved_corners_grid نگاه کنیم، میبینیم که هر گوشه به سلول شبکهای که در آن قرار دارد متصل است.
#> Simple feature collection with 41222 features and 3 fields
#> Geometry type: MULTIPOLYGON
#> Dimension: XY
#> Bounding box: xmin: -122.8368 ymin: 45.43254 xmax: -122.472 ymax: 45.65289
#> Geodetic CRS: WGS 84
#> # A tibble: 41,222 × 4
#> grid_id geometry objectid ramp_style
#> * <int> <MULTIPOLYGON [°]> <int> <chr>
#> 1 1 (((-122.7437 45.43474, -122.7437 45.43446, -122.… NA <NA>
#> 2 2 (((-122.7419 45.43328, -122.7412 45.43327, -122.… 23683 Unimproved
#> 3 2 (((-122.7419 45.43328, -122.7412 45.43327, -122.… 23684 Unimproved
#> 4 2 (((-122.7419 45.43328, -122.7412 45.43327, -122.… 23685 Unimproved
#> 5 2 (((-122.7419 45.43328, -122.7412 45.43327, -122.… 23686 Unimproved
#> 6 2 (((-122.7419 45.43328, -122.7412 45.43327, -122.… 23687 Unimproved
#> 7 2 (((-122.7419 45.43328, -122.7412 45.43327, -122.… 23688 Unimproved
#> 8 3 (((-122.7383 45.43325, -122.7383 45.43325, -122.… 23692 Unimproved
#> 9 3 (((-122.7383 45.43325, -122.7383 45.43325, -122.… 23696 Unimproved
#> 10 3 (((-122.7383 45.43325, -122.7383 45.43325, -122.… 23697 Unimproved
#> # ℹ 41,212 more rows
از آنجا، باید درصد گوشههای بهبود نیافته در هر شبکه را محاسبه کنیم. میتوانیم این کار را با کمی دستکاری دادههای اولیه با استفاده از توابع مختلف {dplyr} انجام دهیم. کد زیر همچنین نشان میدهد که ما از st_drop_geometry() برای تبدیل دادههای مکانی به یک فریم دادهی معمولی استفاده میکنیم، قبل از اینکه بعداً آن را با تابع st_as_sf() به دادههای مکانی تبدیل کنیم (ما این کار را برای سرعت بخشیدن به کد خود انجام میدهیم، که معمولاً روی دادههای مکانی به کندی اجرا میشود).
unimproved_corners_grid_pct |>
improved_corners_grid |>
st_drop_geometry() |>
count(grid_id, ramp_style) |>
complete(grid_id, ramp_style) |>
group_by(grid_id) |>
mutate(pct = n / sum(n, na.rm = TRUE)) |>
ungroup() |>
select(-n) |>
pivot_wider(
id_cols = grid_id,
names_from = ramp_style,
values_from = pct
) |>
mutate(
pct = case_when(
is.na(Unimproved) & Improved == 1 ~ 0,
.default = Unimproved
)
) |>
select(grid_id, pct) |>
left_join(
portland_grid_map,
join_by(grid_id)
) |>
st_as_sf()
حالا بیایید به شیء unimproved_corners_grid_pct خود نگاهی بیندازیم. همانطور که میبینید، اکنون برای هر سلول شبکه یک ردیف داریم، به همراه یک متغیر pct که درصد گوشههای بهبود نیافته در آن سلول را نشان میدهد.
#> Simple feature collection with 5725 features and 2 fields
#> Geometry type: MULTIPOLYGON
#> Dimension: XY
#> Bounding box: xmin: -122.8368 ymin: 45.43254 xmax: -122.472 ymax: 45.65289
#> Geodetic CRS: WGS 84
#> # A tibble: 5,725 × 3
#> grid_id pct geometry
#> <int> <dbl> <MULTIPOLYGON [°]>
#> 1 1 NA (((-122.7437 45.43474, -122.7437 45.43446, -122.7437 45.43419,…
#> 2 2 1 (((-122.7419 45.43328, -122.7412 45.43327, -122.7411 45.43327,…
#> 3 3 1 (((-122.7383 45.43325, -122.7383 45.43325, -122.7381 45.43325,…
#> 4 4 NA (((-122.7346 45.43322, -122.7334 45.43321, -122.7334 45.43321,…
#> 5 5 NA (((-122.731 45.43435, -122.7309 45.43435, -122.7305 45.43435, …
#> 6 6 NA (((-122.7112 45.43474, -122.7112 45.43469, -122.7103 45.43468,…
#> 7 7 NA (((-122.7047 45.43474, -122.7046 45.43472, -122.7046 45.4347, …
#> 8 8 1 (((-122.7018 45.43404, -122.7011 45.43387, -122.701 45.43384, …
#> 9 9 1 (((-122.6982 45.43255, -122.6981 45.43255, -122.6978 45.43254,…
#> 10 10 NA (((-122.6841 45.43474, -122.6841 45.43471, -122.6841 45.4346, …
#> # ℹ 5,715 more rows
ساخت نقشه حرارتی با ggplot
پس از ایجاد یک شبکه، برش آن به مرزهای پورتلند، اتصال دادههایمان در مورد گوشههای بهبود یافته و محاسبه درصد گوشههای بهبود نیافته در هر سلول شبکه، اکنون آماده ایجاد نقشه حرارتی خود هستیم. کد زیر نقشه حرارتی را ایجاد میکند.
ggplot() +
geom_sf(data = portland_boundaries) +
geom_sf(
data = unimproved_corners_grid_pct,
aes(fill = pct),
color = "white"
) +
labs(fill = NULL, title = "Percentage of unimproved corners in Portland") +
scale_fill_viridis_c(
option = "E",
na.value = "gray90",
limits = c(0, 1),
labels = percent_format()
) +
theme_void() +
theme(
plot.title = element_text(
hjust = 0.5,
face = "bold",
margin = margin(b = 10, unit = "pt")
),
legend.key.width = unit(1.5, "cm"),
legend.key.height = unit(0.5, "cm"),
legend.position = "top"
)
نتیجهی این کد، یک نقشهی حرارتی (heatmap) زیبا است که مناطقی از پورتلند را که گوشههای بهبود نیافتهی بیشتری دارند، هایلایت میکند.
خلاصه
همانطور که مشاهده کردید، فرآیند ایجاد یک نقشه حرارتی در ggplot کمی پیچیده است، بنابراین بیایید خلاصه کنیم:
- وارد کردن دادهها در گوشههای بهبود یافته و دادههای مربوطه
- ایجاد یک نقشه شبکهای بر اساس دادههای مرزها
- ادغام دادهها در گوشههای بهبود یافته با نقشه شبکهای
- محاسبه درصد گوشههای بهبود نیافته در هر سلول شبکه
- دادههای حاصل را با سلولهایی با درصد بالاتر گوشههای بهبود نیافته در رنگهای مختلف، نقشهبرداری کنید
در حالی که ما مثالی در مورد ایجاد یک نقشه حرارتی از گوشههای بهبود نیافته در پورتلند ارائه دادیم، میتوانید از این فرآیند برای ایجاد نقشههای حرارتی برای هر نتیجهای در هر مکانی استفاده کنید. برای ایجاد نقشههای حرارتی خود موفق باشید!
دوره آموزشی زبان برنامه نویسی R »کلیک کنید» یک برنامه جامع است که بر توسعه محاسبات آماری و علم دادهها ، ایجاد اشکال گرافیکی و نمودارها و تحلیل سریهای زمانی، رگرسیون خطی و…. با استفاده از ابزار R تمرکز دارد.
.
سپاسگذاریم از وقتی که برای خواندن این مقاله گذاشتید.
.
برای خرید لایسنس تبلو Tableau کلیک کنید
.
برای مشاهده ویدیوهای آموزشی داده کاوی و هوش تجاری ما را در شبکه های اجتماعی دنبال کنید
Youtube Chanel :VISTA Data Mining
Aparat Chanel: VISTA Data Mining
Instagram Chanel: VISTA Data Mining
Telegram Chanel: VISTA Data Mining
Linkedin Chanel: VISTA Company




