Menu
flag Ar iconالعربيةdown icon

ggplot2 في R: دليل المبتدئين إلى قواعد الرسوميات

كيف تعمل ggplot2: النموذج الذهني القائم على البيانات + aes() + geom، والربط مقابل الضبط في السمات الجمالية، وlabs()، وfacet_wrap()، والسمات، وحفظ الرسوم بـ ggsave().

‏ggplot2 تبني الرسوم من طبقات

‏ggplot2 هي أوسع حزم الرسم انتشارًا في R، والسبب الذي يجعل الناس يقسمون بها فكرة تصميمية: قواعد الرسوميات. فـ base R يعطيك دالة لكل مخطط، مثل plot() وhist() وbarplot()، ولكل منها وسائطها الخاصة. أما ggplot2 فتعطيك مجموعة صغيرة من القطع القابلة للتركيب، وهي مجموعة بيانات، وربط من الأعمدة إلى الخصائص البصرية، وطبقات رسم، تتحد بـ + في أي مخطط. تعلّم القواعد مرة واحدة فيصبح كل نوع مخطط جديد الجملة نفسها بكلمة واحدة مبدَّلة. ومن باب المكافأة، تبدو القيم الافتراضية (لوحة رمادية، ومحاور معقولة، ومفاتيح إيضاح تلقائية) صالحة للعرض دون أي جهد تنسيقي.

وهي حزمة إضافية، لذا تحتاج إلى تثبيت لمرة واحدة وتحميل في كل جلسة:

install.packages("ggplot2")   # once, on your machine
library(ggplot2)              # at the top of every script that uses it

وثمة توقع ينبغي معرفته مسبقًا: تريد ggplot2 إطار بيانات لا متجهات متفرقة، ويفضَّل أن يكون بالصيغة الطويلة المرتبة، أي صف لكل ملاحظة وعمود لكل متغير. وإذا كانت بياناتك عريضة، فإن تطويلها أولًا يذيب عادةً ما بدا مشكلة في الرسم.

النموذج الذهني: البيانات والربط والشكل الهندسي

يجيب كل رسم ggplot عن ثلاثة أسئلة، سؤال لكل جزء:

  1. البيانات: أي إطار بيانات؟ ‏ggplot(mtcars, ...)
  2. الربط: أي الأعمدة يقود أي الخصائص البصرية؟ ‏aes(x = wt, y = hp)
  3. الشكل الهندسي: كيف ينبغي رسم الملاحظات؟ ‏+ geom_point()

وهذا هو التشريح رمزًا برمز:

ggplot(mtcars, aes(x = wt, y = hp)) +
    geom_point()
  • تبدأ ggplot(mtcars, ...) رسمًا بياناته الافتراضية mtcars. وهي وحدها ترسم لوحة رمادية فارغة بلا طبقات بعد.
  • aes(x = wt, y = hp) هي الربط الجمالي: فالموضع الأفقي يأتي من عمود wt، والموضع الرأسي من hp. ولاحظ أنك تكتب أسماء الأعمدة مجردة لا mtcars$wt، لأن الربط يُقيَّم داخل البيانات التي زوّدتها.
  • تضيف + geom_point() طبقة ترسم كل صف نقطةً. والعلامة + هي فعلًا جمع للطبقات: فالرسم كائن تبنيه تدريجيًا، وتستطيع الاستمرار في الإضافة، من شكل هندسي آخر إلى تسميات إلى سمة، كل منها بـ + إضافية.

شغّلها فتحصل على مخطط انتشار الوزن مقابل القدرة الحصانية نفسه الوارد في نسخة base R في دليل مخطط الانتشار، على لوحة رمادية بخطوط شبكية بيضاء. وبدّل geom_point() بـ geom_line() فيصبح الربط نفسه مخططًا خطيًا، وتلك هي القواعد وهي تؤدي عملها.

الأشكال الهندسية التي ستستخدمها فعلًا

عشرة أشكال هندسية أو نحوها تغطي كل العمل اليومي تقريبًا:

geom_point()       # scatter plot: two numeric variables
geom_line()        # line chart: trends over an ordered variable
geom_col()         # bar chart from pre-computed heights (needs y)
geom_bar()         # bar chart that counts raw rows for you (no y)
geom_histogram()   # distribution of one numeric variable (set binwidth)
geom_boxplot()     # distributions compared across groups
geom_smooth()      # fitted trend line; method = "lm" for straight

وتتراكم الطبقات، وهنا تبدأ ggplot2 في التفوق على base R من حيث القدرة التعبيرية: فـ geom_point() + geom_smooth(method = "lm") مخطط انتشار مع خط انحدار ونطاق ثقة، في سطر واحد سهل القراءة. ولأن الرسوم كائنات، تستطيع أيضًا حفظ قاعدة والتفرع منها:

p <- ggplot(mtcars, aes(x = wt, y = hp)) + geom_point()

p + geom_smooth(method = "lm")   # one variant
p + geom_smooth()                # another (loess curve)

الربط مقابل الضبط: التباس aes() الكلاسيكي

الخطأ الوحيد الذي يرتكبه كل مبتدئ في ggplot2، عادةً في أسبوعه الأول، هو وضع لون حرفي داخل aes(). والقاعدة قصيرة: داخل aes() يعني "يتغير بتغير البيانات"، وخارجها يعني "إعداد ثابت"، والموضعان يفعلان أشياء مختلفة تمامًا:

# MAPPING: color varies by a column - each cylinder count gets its own
# color, and a legend appears automatically
ggplot(mtcars, aes(x = wt, y = hp, color = factor(cyl))) +
    geom_point(size = 2)

# SETTING: every point is literally steelblue - no legend, no mapping
ggplot(mtcars, aes(x = wt, y = hp)) +
    geom_point(color = "steelblue", size = 2)

وأما المصيدة نفسها:

# WRONG: "blue" inside aes() is treated as data, not as a color
ggplot(mtcars, aes(x = wt, y = hp, color = "blue")) +
    geom_point()

يرسم هذا نقاطًا وردية سلمونية مع مفتاح إيضاح مدخلته الوحيدة مسمّاة "blue". والسبب أن aes() تربط الأعمدة بالخصائص، فتنشئ color = "blue" عمودًا وهميًا ذا فئة واحدة قيمته الكلمة "blue" في كل مكان، ويسند ggplot إلى تلك الفئة لونه الافتراضي الأول، الذي يصادف أنه سلموني مائل إلى الحمرة. وإذا كنت تقصد "اجعل النقاط زرقاء" فاللون يوضع خارج الربط: geom_point(color = "blue"). والقاعدة نفسها تحكم size وshape وfill وalpha. (ولاحظ أيضًا factor(cyl) في مثال الربط: فـ cyl عددي، وتغليفه بـ factor() يطلب ألوانًا متمايزة لكل مجموعة بدل تدرج لوني متصل.)

التسميات والتقسيمات والسمات

تسمّي labs() كل شيء في مكان واحد، والرسم لا يكتمل حتى تكون له تسميات حقيقية:

ggplot(mtcars, aes(x = wt, y = hp, color = factor(cyl))) +
    geom_point(size = 2) +
    labs(title = "Horsepower vs. weight",
         x     = "Weight (1000 lbs)",
         y     = "Horsepower",
         color = "Cylinders")

التقسيمات هي الميزة البارزة في ggplot2: تقسّم رسمًا واحدًا إلى مضاعفات صغيرة، لوحة لكل مجموعة، بمحاور مشتركة لتقارن اللوحات بصدق:

ggplot(mtcars, aes(x = wt, y = hp)) +
    geom_point() +
    facet_wrap(~ cyl)

تظهر ثلاث لوحات، واحدة لكل من السيارات ذات 4 و6 و8 أسطوانات، موزعة على شبكة مع كتابة قيمة المجموعة فوق كل لوحة. وفي base R يكون هذا شعوذة بـ par(mfrow) مع ضبط يدوي للحدود المشتركة، أما هنا فسطر واحد. والتقسيم يكافئ البيانات المرتبة، ولهذا تتزاوج ggplot2 بشكل طبيعي جدًا مع سلسلة dplyr: صفِّ ولخّص، ثم مرّر النتيجة مباشرة إلى ggplot().

السمات تعيد تنسيق الحبر غير البياني في استدعاء واحد: + theme_minimal() (خلفية بيضاء نظيفة)، أو + theme_bw()، أو + theme_classic() (محاور فقط بلا شبكة)، أو الرمادي الافتراضي. اختر واحدة لكل مشروع والزمها، فالتقرير الذي تتشارك كل أشكاله سمة واحدة يُقرأ مستندًا واحدًا لا دفتر قصاصات.

الحفظ بـ ggsave() ومتى يظل base R كافيًا

تكتب ggsave() أحدث رسم إلى القرص، مستنتجةً الصيغة من امتداد الملف:

ggsave("hp-vs-weight.png", width = 8, height = 5)          # last plot shown
ggsave("hp-vs-weight.pdf", plot = p, width = 8, height = 5) # a saved object

وقيمتا width وheight بالبوصة افتراضيًا، فاضبطهما صراحةً لأن أحجام الخطوط تتناسب مع أبعاد المخرجات، ونادرًا ما تطابق القيم الافتراضية وجهة الشكل.

وأما متى تتكلف العناء: فلنظرة من خمس ثوانٍ على متغير واحد أثناء التحليل، تكون plot() وأخواتها في base R أقل كتابة وبلا أي اعتماديات، فلا جائزة على استخدام ggplot2 في كل مكان. وتستحق ggplot2 مكانها في اللحظة التي يشمل فيها الشكل مجموعات أو مفاتيح إيضاح أو تقسيمات أو جمهورًا: فالقواعد تتوسع مع تعقيد لا يتعامل معه الرسم في base إلا بجهد.

الخلاصة

  • تؤلف ggplot2 كل مخطط من بيانات + ربط aes() + طبقات geom، متصلة بـ +، فتعلّم القواعد مرة واحدة وأعد استخدامها لكل نوع مخطط.
  • تربط aes() الأعمدة بالخصائص البصرية بأسماء أعمدة مجردة تُقيَّم داخل إطار بياناتك.
  • داخل aes() = يتغير بتغير البيانات (ويحصل على مفتاح إيضاح)، وخارجها = إعداد ثابت. وaes(color = "blue") هو الخلل الكلاسيكي.
  • labs() للعناوين، وfacet_wrap(~ group) للمضاعفات الصغيرة، وtheme_minimal() وأخواتها للتنسيق، وggsave() بأبعاد صريحة للتصدير.
  • للنظرة الفردية السريعة: ‏base R. وللمجموعات والتقسيمات والجمهور: ‏ggplot2.

بهذا يُغلق فصل الرسم، ومن هنا تكون الخطوة الطبيعية التالية الإحصاءات الوصفية، أي وضع أرقام للأشكال التي تكشفها هذه الرسوم.

الأسئلة الشائعة

ما هي ggplot2 في R؟

‏ggplot2 هي أشهر حزم الرسم في R. وبدل دالة لكل نوع مخطط، تؤلف كل رسم من القطع الثلاث نفسها: إطار بيانات، وربط aes() من الأعمدة إلى الخصائص البصرية، وطبقة geom_*() واحدة أو أكثر، وتصلها بـ +. وهي جزء من tidyverse.

كيف تثبّت ggplot2؟

شغّل install.packages("ggplot2") مرة واحدة، ثم library(ggplot2) في أعلى كل سكربت يستخدمها. فالتثبيت يضع الحزمة على جهازك، وتحمّلها library() في الجلسة الحالية.

ماذا تفعل aes() في ggplot2؟

تربط aes() أعمدة بياناتك بالخصائص البصرية: فـ aes(x = wt, y = hp, color = factor(cyl)) تعني أن الموضع الأفقي يأتي من wt، والموضع الرأسي من hp، ولون النقطة من عدد الأسطوانات. وكل ما يقع داخل aes() يتغير بتغير البيانات، وكل ما يقع خارجها إعداد ثابت.

لماذا لا تظهر نقاط ggplot باللون الذي طلبته؟

لأنك وضعت اللون داخل aes(): فـ aes(color = "blue") لا تضبط لونًا بل تربط فئة مخترعة اسمها "blue"، فيختار ggplot لونه الافتراضي ويضيف مفتاح إيضاح. ولضبط لون حرفي، ضعه خارج الربط: geom_point(color = "blue").

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن