By | August 7, 2021
[This article was first published on R on R (for ecology), and kindly contributed to R-bloggers]. (Anda dapat melaporkan masalah tentang konten di halaman ini di sini)


Ingin berbagi konten Anda di R-blogger? klik di sini jika Anda memiliki blog, atau di sini jika tidak.

Scatterplots adalah salah satu jenis visualisasi data paling umum yang akan Anda temui sebagai ahli biologi. Mereka menyajikan hubungan antara dua variabel kontinu. Kita mungkin menganggapnya biasa saja karena kesederhanaannya, tetapi kita tidak boleh berasumsi seperti intuisi yang dengannya kita dapat melihat dan memahami angka-angka ini. Mereka adalah alat yang ampuh, tetapi yang saya yakini perlu mendapat perhatian lebih. Lihat artikel yang sangat keren ini dari New Yorker tentang ‘Ketika grafik adalah masalah hidup dan mati’ untuk sejarah lebih lanjut tentang masalah ini.

Sepanjang tahun-tahun sekolah pascasarjana saya dan seterusnya, saya telah berulang kali menemukan plot sebar yang hampir mengalahkan tujuan membantu kita dengan mudah memahami hubungan antara dua variabel. Berikut adalah contoh tipikal dari jenis plot yang pernah saya lihat terlalu sering:

Ada beberapa masalah di sini, tetapi tanpa menjelaskan lebih lanjut, berikut adalah data yang sama setelah beberapa penyesuaian visual:

Jauh lebih mencolok dan mudah dibaca, bukan?

Dengan kata lain, walaupun datanya mungkin akurat, desain visual sebenarnya dari scatterplot sering diabaikan dan tidak dijaga. Tidak seperti uji statistik, tujuan visualisasi data bersifat subjektif—untuk membantu pemirsa memahami hubungan atau cerita tertentu. Untuk alasan itu, penting bagi kita untuk mengambil pendekatan subjektif, dan berani saya katakan estetika, untuk memastikan plot sebar (dan semua jenis plot lainnya, sungguh) menarik secara visual dan mudah dipahami dalam sekejap.

Saya punya firasat bahwa alasan utama plot seperti yang pertama di atas begitu umum adalah karena kurangnya pengetahuan tentang cara menyesuaikan plot dengan mudah di R. Sayangnya, bahkan ggplot2—yang dipuji karena kemudahannya untuk dibuat. visualisasi berkualitas baik—tidak begitu bagus di luar kotak.

Oleh karena itu posting blog ini

Berikut adalah tutorial sederhana tentang cara membuat ulang versi bagus dari plot di atas menggunakan paket R ‘dasar’. Kuncinya hanya dengan menyertakan beberapa parameter dan fungsi tambahan. Di masa depan saya dapat memperbarui posting ini dengan cara melakukan ini menggunakan ggplot2.

Pertama, mari kita memuat data. Dalam hal ini kami menggunakan dataset bawaan pada pengukuran kualitas udara di New York dari Mei hingga September 1973:

# Load the built-in data:
data(airquality)
help(airquality)
head(airquality)

## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 NA NA 14.3 56 5 5
## 6 28 NA 14.9 66 5 6

Untuk tutorial ini kami hanya tertarik pada konsentrasi ozon, yang diukur dalam bagian per juta (ppm), dan kecepatan angin, yang diukur dalam mil per jam (MPH). Untuk mendapatkan info ini, saya hanya menjalankan fungsi ‘bantuan (kualitas udara)’ untuk menampilkan deskripsi data ini.

Selanjutnya, mari kita mulai dengan plot yang dibuat menggunakan fungsi ‘plot()’ langsung dari kotak:

plot(Ozone ~ Wind, data=airquality)

Variabel mana pun yang Anda inginkan pada sumbu Y berada di sebelah kiri tilde ‘~’ dan sumbu X berada di sebelah kanan tilde. Hal yang menarik tentang notasi ini adalah Anda bisa langsung menggunakan nama kolom dari data yang ingin Anda plot. Dalam hal ini kami menetapkan argumen ‘data’ ke kerangka data kami ‘kualitas udara’, dan ‘Ozon’ dan ‘Angin’ adalah nama kolom yang diambil langsung dari kerangka data tersebut.

Selanjutnya, hapus semua sumbu dan tanda centang dari plot sehingga kita bisa mulai dengan yang bersih:

plot(Ozone ~ Wind, data=airquality, xaxt="n", yaxt="n", ylab="", xlab="")

Kemudian kita akan menambahkan kembali sumbu baru yang sepenuhnya dapat disesuaikan menggunakan fungsi ‘axis()’:

plot(Ozone ~ Wind, data=airquality, xaxt="n", yaxt="n", ylab="", xlab="")
# add the wind speed axis:
axis(side=1, at=seq(0, max(airquality$Wind, na.rm=T), 2), padj=-0.8)
# add the Ozone axis:
axis(side=2, at=seq(0, max(airquality$Ozone, na.rm=T), 20), hadj=0.8, las=2)

Argumen ‘sisi’ menunjukkan sisi mana dari grafik yang kita tambahkan sumbunya. Sisi 1, 2, 3, dan 4 berturut-turut adalah bawah, kiri, atas, dan kanan. Kemudian, ‘at’ adalah tempat kita memberi tahu fungsi tempat meletakkan sumbu kutu. Misalnya, inilah yang kami gunakan untuk argumen itu:

# This finds the maximum value for wind:
max(airquality$Wind, na.rm=T)

## [1] 20.7

# Then use that in the 'seq()' function to create the sequence of places for the tickmarks:
seq(from = 0, to = max(airquality$Wind, na.rm=T), by = 2)

## [1] 0 2 4 6 8 10 12 14 16 18 20

Argumen ‘padj’ dan ‘hadj’ (penyesuaian tegak lurus dan penyesuaian horizontal) digunakan untuk menyenggol teks label tanda centang sumbu agar berjajar lebih rapi. Bermain-main dengan nilai-nilai itu untuk melihat apa yang Anda dapatkan. Akhirnya, argumen ‘las’ ketika disetel ke 2, mengubah tanda centang sumbu y secara horizontal sehingga lebih mudah dibaca dan semuanya pas pada sumbu dengan rapi.

Selanjutnya, tambahkan label nama sumbu menggunakan fungsi ‘mtext’. Itu selalu penting untuk menambahkan unit ke label ini, yang saya lakukan. Argumen ‘garis’ adalah seberapa jauh dari tepi plot yang Anda inginkan agar label muncul. ‘cex’ mempengaruhi ukuran teks, dan akhirnya, ‘font’ digunakan untuk membuat teks menjadi tebal. Anda dapat mengatur ‘font’ menjadi 1, 2, 3, atau 4, untuk masing-masing normal, bold, italic, atau italic + bold. Bermain-main dengan semua parameter itu untuk melihat bagaimana itu mengubah gambar.

plot(Ozone ~ Wind, data=airquality, xaxt="n", yaxt="n", ylab="", xlab="")
# add the wind speed axis:
axis(side=1, at=seq(0, max(airquality$Wind, na.rm=T), 2), padj=-0.8)
# add the Ozone axis:
axis(side=2, at=seq(0, max(airquality$Ozone, na.rm=T), 20), hadj=0.8, las=2)
# add in the labels for each axis:
mtext(side=1, "Wind Speed (mph)", line=2.8, cex=1.5, font=2)
mtext(side=2, "Ozone Concentration (ppb)", line=2.8, cex=1.4, font=2)

Sekarang kita memiliki semua elemen di sana, mari kita sesuaikan poinnya sedikit. Saya benar-benar bukan penggemar poin garis besar lingkaran. Sesuatu tentang itu tidak memberikan penekanan yang ingin saya lihat pada gambar (jangan ragu untuk tidak setuju!). Sebagai gantinya, saya lebih suka mengisi poin menggunakan argumen ‘pch = 16’, dan kemudian membuatnya sedikit lebih besar dengan argumen ‘cex’ (keduanya dalam fungsi ‘plot()’):

plot(Ozone ~ Wind, data=airquality, xaxt="n", yaxt="n", ylab="", xlab="", pch=16, cex=1.5)
# add the wind speed axis:
axis(side=1, at=seq(0, max(airquality$Wind, na.rm=T), 2), padj=-0.8)
# add the Ozone axis:
axis(side=2, at=seq(0, max(airquality$Ozone, na.rm=T), 20), hadj=0.8, las=2)
# add in the labels for each axis:
mtext(side=1, "Wind Speed (mph)", line=2.8, cex=1.5, font=2)
mtext(side=2, "Ozone Concentration (ppb)", line=2.8, cex=1.4, font=2)

Saya pikir itu terlihat jauh lebih baik. Satu-satunya masalah di sini adalah banyak titik yang tumpang tindih sehingga Anda kehilangan kemampuan untuk melihat kelompok tersebut. Untuk mengatasinya kita bisa membuat warna titik menjadi transparan. Ini sebenarnya sangat mudah dilakukan dengan menggunakan paket ‘ggplot2’, tetapi kita juga dapat melakukannya dengan paket ‘base’—hanya membutuhkan sedikit lebih banyak kode. Saya membuat fungsi untuk membuat membuat warna transparan sedikit lebih mudah:

### transparent colors function
t_col <- function(color, opacity = 0.5) {
rgb.val <- col2rgb(color)
t.col <- rgb(rgb.val[1], rgb.val[2], rgb.val[3], max = 255, alpha = (opacity)*255)
invisible(t.col)
}

Fungsi ini pada dasarnya mengambil dua argumen: ‘warna’ yang merupakan warna yang ingin Anda buat transparan, dan kemudian ‘opacity’ yang beralih dari 0 ke 1, dengan 0 benar-benar transparan, dan 1 tidak ada transparansi. Menambahkan fungsi ini ke plot kami terlihat seperti ini:

plot(Ozone ~ Wind, data=airquality, xaxt="n", yaxt="n", ylab="", xlab="", pch=16, cex=1.5,
col=t_col("black",0.6))
# add the wind speed axis:
axis(side=1, seq(0, max(airquality$Wind, na.rm=T), 2), padj=-0.8)
# add the Ozone axis:
axis(side=2, at=seq(0, max(airquality$Ozone, na.rm=T), 20), hadj=0.8, las=2)
# add in the labels for each axis:
mtext(side=1, "Wind Speed (mph)", line=2.8, cex=1.5, font=2)
mtext(side=2, "Ozone Concentration (ppb)", line=2.8, cex=1.4, font=2)

Hampir selesai! Saya suka menambahkan sedikit ruang putih di sekitar tepi titik sehingga tidak mengalami “efek tepi” dan memungkinkan Anda untuk “mundur” secara kiasan saat melihat semua data. Juga tidak ada alasan kecepatan angin tidak boleh dimulai dari nol karena kita hampir mendekati itu. Jadi untuk menambahkan spasi dan memperluas sumbu, kita hanya mengubah batas sumbu menggunakan argumen ‘xlim’ dan ‘ylim’ di fungsi ‘plot()’. Mereka masing-masing mengambil vektor dua nilai yang menunjukkan batas minimum dan maksimum setiap sumbu:

plot(Ozone ~ Wind, data=airquality, xaxt="n", yaxt="n", ylab="", xlab="", pch=16, cex=1.5,
col=t_col("black",0.6), ylim=c(0,185), xlim=c(0,22))
# add the wind speed axis:
axis(side=1, seq(0, max(airquality$Wind, na.rm=T), 2), padj=-0.8)
# add the Ozone axis:
axis(side=2, at=seq(0, max(airquality$Ozone, na.rm=T), 20), hadj=0.8, las=2)
# add in the labels for each axis:
mtext(side=1, "Wind Speed (mph)", line=2.8, cex=1.5, font=2)
mtext(side=2, "Ozone Concentration (ppb)", line=2.8, cex=1.4, font=2)

Kita akan mengakhiri dengan menggunakan fungsi ‘par()’ untuk mengatur margin plot. Saya tidak suka seberapa dekat label sumbu Y dengan tepi gambar. Argumen ‘mar’ adalah untuk mengatur margin di sekitar tepi gambar. Saya tidak yakin unit apa yang ada di dalamnya, tetapi mainkan dengan angka-angka sampai Anda mendapatkan sesuatu yang terlihat bagus. Empat nilai dalam vektor mewakili empat sisi dalam urutan yang sama dengan argumen ‘sisi’ yang digunakan untuk sumbu: bawah, kiri, atas, dan kanan:

Berikut adalah plot lagi dengan warna latar belakang sehingga Anda dapat melihat apa yang saya maksud:

Dan setelah kita menambahkan ‘par(mar=c(5,5,2,2))’:

Itu terlihat bagus! Jadi di sini adalah kode terakhir:

par(mar=c(5,5,2,2))
plot(Ozone ~ Wind, data=airquality, xaxt="n", yaxt="n", ylab="", xlab="", pch=16, cex=1.5,
ylim=c(0,185), xlim=c(0,22), col=t_col("black",0.6))
mtext(side=1, "Wind Speed (mph)", line=2.8, cex=1.5, font=2)
axis(side=1, seq(0, max(airquality$Wind)+2, 2), padj=-0.8)
mtext(side=2, "Ozone Concentration (ppb)", line=2.8, cex=1.4, font=2)
axis(side=2, at=seq(0, 185, 20), hadj=0.8, las=2)

Terakhir (dan mungkin yang paling penting), ketika Anda menyimpan gambar Anda dengan mengklik ‘Ekspor’ di atas panel ‘Plot’ di R Studio, Anda akan memiliki opsi untuk mengubah ukuran dimensi gambar dan melihat pratinjau tampilannya dengan dimensi yang berbeda . Jangan abaikan langkah penting untuk memastikan dimensi gambar diatur ke ukuran yang mempertimbangkan proporsi semua elemen dalam gambar. Hanya bermain-main dengan ukuran dan Anda akan melihat apa yang saya maksud. Inilah yang Anda tuju:


Bukan ini:

Atau, jika Anda ingin ukuran gambar juga tetap ada dalam kode, buat jendela ‘quartz()’ (jika menggunakan mac) atau jendela windows() (jika menggunakan PC). Setel ‘tinggi’ dan ‘lebar’ dalam fungsi-fungsi itu ke ukuran yang diinginkan (saya yakin satuannya adalah inci) dan jalankan fungsi itu sebelum kode yang membuat plot. Ini akan membuka jendela grafis eksternal yang berukuran sesuai spesifikasi Anda dan Anda kemudian dapat pergi ke menu file di bagian atas layar Anda untuk menyimpan gambar sebagai PDF.

Anda juga dapat menyimpan langsung ke file jendela grafik. Berikut adalah kode terakhir untuk cara melakukannya:

pdf(file="my_scatterplot.pdf",width=7,height=4.5)
par(mar=c(5,5,2,2))
plot(Ozone ~ Wind, data=airquality, xaxt="n", yaxt="n", ylab="", xlab="", pch=16, cex=1.5,
ylim=c(0,185), xlim=c(0,22), col=t_col("black",0.6))
mtext(side=1, "Wind Speed (mph)", line=2.8, cex=1.5, font=2)
axis(side=1, seq(0, max(airquality$Wind)+2, 2), padj=-0.8)
mtext(side=2, "Ozone Concentration (ppb)", line=2.8, cex=1.4, font=2)
axis(side=2, at=seq(0, 185, 20), hadj=0.8, las=2)
dev.off()

Cukup gunakan fungsi ‘pdf()’ untuk mengatur nama file dan direktori tempat file akan disimpan dan tentukan tinggi dan lebarnya dalam inci. Anda dapat bermain-main dengan pengukuran tersebut sampai Anda menemukan sesuatu yang berhasil. Kemudian jalankan kode yang membuat plot. Dan terakhir, jalankan ‘dev.off()’ untuk menutup perangkat grafis itu.

Saya sarankan untuk selalu menyimpan gambar Anda sebagai PDF untuk mempertahankan kualitas maksimal. Lihat posting blog luar biasa lainnya oleh David Smith ini dengan detail lebih lanjut tentang bagaimana dan mengapa menyimpan gambar Anda dalam format tertentu.

Bagus sekali! Itu saja untuk saat ini. Apakah menurut Anda ini lebih mudah dilakukan dengan ggplot? Saya akan menindaklanjuti dengan pembaruan atau posting tentang itu juga.

Jika Anda menyukai artikel ini, beri tahu saya apa yang mungkin ingin Anda lihat selanjutnya di komentar di bawah.


Jika Anda menyukai posting ini dan ingin mempelajari lebih lanjut, lihat kursus online saya tentang dasar-dasar lengkap R untuk ekologi:

Pastikan juga untuk memeriksa R-blogger untuk tutorial hebat lainnya tentang belajar R