R: موضوعات R ggplot2 والتصميم: دليل شامل لـ `theme`

آخر تحديث: 2026-08-26

يعد المظهر الافتراضي theme_gray() في ggplot2 جيدًا بالفعل، ولكن لإنشاء رسوم بيانية «بجودة النشر»، ستحتاج إلى ضبط هذا المظهر بدقة. في هذا الدرس، سنتعرف على نظام السمات في ggplot2: بدءًا من السمات الثماني المدمجة، مرورًا بالضبط الدقيق من theme() إلى labs وscale، وصولًا إلى المخرجات عالية الدقة باستخدام ggsave.

بعد الانتهاء من هذا الدرس، ستتمكن من ضبط أي رسم بياني في ggplot2 وفقًا لمعايير «الجاهزية للنشر» — مع التحكم الكامل في النص والألوان والمفاتيح التوضيحية والهوامش والمحاور.

1. ما ستتعلمه



2. قصة «الرسم البياني الاحترافي»

(1) المشكلة: تبدو الصورة الافتراضية «مدرسية» للغاية

أنشأ بوب رسمًا بيانيًّا باستخدام ggplot2، فقال المدير: «هذا تقرير موجه للمستثمرين — إنه بسيط للغاية».

(2) خيارات التصور في ggplot2

R
library(ggplot2)
library(hrbrthemes)  # Professional Theme Packages

p <- ggplot(sales, aes(x = quarter, y = sales, color = city, group = city)) +
  geom_line(linewidth = 1.2) +
  geom_point(size = 3) +
  scale_color_brewer(palette = "Set1") +
  labs(
    title = "2024 Q1-Q4 Sales Trends",
    subtitle = "Data Source: Sales System | Chart: Analyst Team",
    caption = "Unit: 10,000 yuan",
    x = "Quarter", y = "Sales (10,000 yuan)",
    color = "City"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 16),
    plot.subtitle = element_text(color = "gray50"),
    legend.position = "top",
    panel.grid.minor = element_blank()
  )

ggsave("professional_report.png", p, width = 10, height = 6, dpi = 300)

3 أسطر من التعليمات البرمجية → رسوم بيانية بجودة النشر.



3. 8 قوالب مدمجة

(1) مقارنة بين الموضوعات

الموضوع النمط السيناريوهات المناسبة
theme_gray() الإعداد الافتراضي (خلفية رمادية) عام
theme_bw() أبيض وأسود ورقة أكاديمية
theme_minimal() أسلوب بسيط (الأكثر استخدامًا) التقارير/العروض التقديمية
theme_classic() كلاسيكي (بدون شبكة) أكاديمي
theme_void() فارغ خريطة/رسم تخطيطي
theme_light() خلفية فاتحة عرض تجريبي
theme_dark() خلفية داكنة مظهر داكن
theme_test() للاختبار تصحيح الأخطاء

(2) مقارنة مع الواقع

R
p <- ggplot(mtcars, aes(wt, mpg)) + geom_point()

p + theme_gray()       # Default
p + theme_minimal()    # Minimalism
p + theme_bw()         # Black and White
p + theme_classic()    # Classic
p + theme_light()      # Light-colored
p + theme_dark()       # Dark
p + theme_void()       # Blank

حجم القاعدة / عائلة القاعدة

R
# Set the font size globally
p + theme_minimal(base_size = 14)

# Set the Global Font
p + theme_minimal(base_family = "SimHei")  # Chinese


4. شجرة عناصر function theme()

(1) بنية العنصر

100%
graph TB
    A[theme Element] --> B[plot Full Image]
    A --> C[axis Coordinate Axes]
    A --> D[legend Legend]
    A --> E[panel Panel]
    A --> F[strip Facet Labels]
    A --> G[title Title]
    
    B --> H[plot.title]
    B --> I[plot.background]
    C --> J[axis.title]
    C --> K[axis.text]
    C --> L[axis.line]
    D --> M[legend.title]
    D --> N[legend.text]
    D --> O[legend.position]
    E --> P[panel.background]
    E --> Q[panel.grid]
    F --> R[strip.text]
    F --> S[strip.background]
    
    style A fill:#fff3cd
    style B fill:#cce5ff
    style C fill:#d4edda
    style D fill:#f8d7da
    style E fill:#e1d4ff
    style F fill:#ffe1e1
    style G fill:#e1ffe1

(2) 4 أنواع من وظائف element_

الوظيفة الغرض تُستخدم لـ
element_text() النص العناوين، وتسميات المحاور، ونص المقياس
element_line() الخطوط خطوط الشبكة، خطوط المحاور
element_rect() مستطيل الخلفية، الحدود، اللوحة
element_blank() إخفاء أي عنصر

(3) المعلمة النصية في دالة element_text()

R
theme(
  plot.title = element_text(
    size = 16,        # Font size
    face = "bold",    # Bold/italics (plain/bold/italic/bold.italic)
    color = "blue",   # Color
    family = "SimHei",# Font
    hjust = 0.5,      # Horizontal Alignment (0=left, 1=right, 0.5=center)
    vjust = 0.5       # Vertical Alignment
  )
)

(4) معلمات الدالة element_line() الخاصة بالخط

R
theme(
  panel.grid.major = element_line(
    color = "gray80",
    linewidth = 0.5,
    linetype = "dashed"   # solid/dashed/dotted
  ),
  panel.grid.minor = element_blank(),  # Hide Secondary Grid
  axis.line = element_line(color = "black", linewidth = 0.8)
)

(5) معلمة المستطيل في دالة element_rect()

R
theme(
  panel.background = element_rect(
    fill = "lightyellow",
    color = "black",
    linewidth = 0.5
  ),
  plot.background = element_rect(fill = "white")
)

(6) element_blank() إخفاء

R
theme(
  panel.grid = element_blank(),         # Hide All Grids
  axis.ticks = element_blank(),         # Hide Scale
  legend.position = "none"              # Hide Legend (Note: No element_blank)
)


5. صقل الموضوعات المشتركة

(1) حجم النص

R
p + theme(
  plot.title = element_text(size = 18, face = "bold"),
  plot.subtitle = element_text(size = 12, color = "gray50"),
  axis.title = element_text(size = 12),
  axis.text = element_text(size = 10),
  legend.title = element_text(size = 11),
  legend.text = element_text(size = 10)
)

(2) خطوط الشبكة

R
p + theme(
  panel.grid.major = element_line(color = "gray90"),
  panel.grid.minor = element_blank(),  # Hide Secondary Grid (More concise)
  panel.border = element_rect(color = "black", fill = NA, linewidth = 0.5)
)

(3) موقع التوضيح

R
# 4 every corner
p + theme(legend.position = "top")
p + theme(legend.position = "bottom")
p + theme(legend.position = "left")
p + theme(legend.position = "right")

# Hide
p + theme(legend.position = "none")

# Coordinate Positioning (In the figure)
p + theme(legend.position = c(0.8, 0.2))  # 80% x, 20% y

(4) محاور الإحداثيات

R
p + theme(
  axis.line = element_line(color = "black", linewidth = 0.8),
  axis.ticks = element_line(color = "black"),
  axis.title.x = element_text(margin = margin(t = 10)),  # X Move the axis title down
  axis.title.y = element_text(margin = margin(r = 10))   # Y Shift the axis title to the left
)


6. الوثائق الكاملة لوظيفة labs()

(1) جميع العلامات

R
p + labs(
  title = "Main Title",
  subtitle = "Subtitle",
  caption = "Data Sources",
  x = "X Axis",
  y = "Y Axis",
  color = "Color Mapping",  # Corresponding aes(color)
  fill = "Fill Mapping",   # Corresponding aes(fill)
  shape = "Shape Mapping",
  size = "Size Mapping"
)

(2) علامات الصيغ الرياضية

R
# For use in formulas quote() or expression
p + labs(
  x = quote(x[i]),
  y = expression(paste("Concentration (", mu, "g/mL)"))
)


7. ألوان scale_color / scale_fill

(1) الألوان المنفصلة (المتغيرات الفئوية)

R
# 1. Specify manually
p + scale_color_manual(values = c("red", "blue", "green", "orange"))

# 2. ColorBrewer Color Palette
p + scale_color_brewer(palette = "Set1")    # Classic 9 colors
p + scale_color_brewer(palette = "Set2")    # Gentle 8 colors
p + scale_color_brewer(palette = "Dark2")   # Dark 8 colors
p + scale_color_brewer(palette = "Pastel1") # Light-colored 9 colors

# 3. viridis (Color-blind-friendly, Recommended)
library(viridis)
p + scale_color_viridis_d()  # Discrete
p + scale_color_viridis_c()  # Consecutive

(2) الألوان المتصلة (المتغيرات المتصلة)

R
# Gradient
p + scale_color_gradient(low = "blue", high = "red")
p + scale_color_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0)
p + scale_color_gradientn(colours = rainbow(7))

(3) التطبيق العملي: أنظمة الألوان الاحترافية

R
# 4 Class Classification
p + scale_color_brewer(palette = "Set1")
# 8 Class Classification
p + scale_color_brewer(palette = "Set2")
# Color-blind-friendly
p + scale_color_viridis_d()
# Academic/Serious
p + scale_color_manual(values = c("#1f77b4", "#ff7f0e", "#2ca02c"))


8. حزم السمات المتخصصة

(1) 8 قوالب من ggthemes

R
install.packages("ggthemes")
library(ggthemes)

p + theme_economist()    # The Economist
p + theme_wsj()           # The Wall Street Journal
p + theme_fivethirtyeight()  # FiveThirtyEight
p + theme_hc()            # Highcharts
p + theme_tufte()         # Tufte Minimalism
p + theme_stata()         # Stata
p + theme_solarized()     # Solarized
p + theme_excel()         # Excel Style

(2) قوالب hrbrthemes التجارية

R
install.packages("hrbrthemes")
library(hrbrthemes)

p + theme_ipsum()         # ipsum Typographic Style
p + theme_ft_rc()         # The Financial Times

(3) السمات المخصصة (تُحدد مرة واحدة، وتُستخدم في كل مكان)

R
# Custom Themes
my_theme <- theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 14),
    panel.grid.minor = element_blank(),
    legend.position = "bottom"
  )

# Global Use
ggplot(df, aes(x, y)) + geom_point() + my_theme


9. ggsave() الحفظ بدقة عالية

(1) 4 معلمات رئيسية

R
ggsave(
  filename,            # File Name
  plot = last_plot(),   # Graph Object (Default: Last Image)
  width = 8,            # Width
  height = 6,           # High
  units = "in",         # Unit in/cm/mm
  dpi = 300             # Resolution
)

(2) التطبيق العملي

R
# PNG Printing Standard (300 dpi)
ggsave("report.png", width = 8, height = 6, dpi = 300)

# High-Definition Screen (150 dpi)
ggsave("screen.png", width = 1920, height = 1080, units = "px", dpi = 150)

# PDF For a thesis (Vector)
ggsave("paper.pdf", width = 8, height = 6)

# Chinese Title (Avoid garbled characters)
ggsave("Chinese.png", width = 8, height = 6, dpi = 300)

(3) تنسيقات متنوعة

التنسيق الامتداد الغرض
PNG .png الويب/المستندات (الأكثر شيوعًا)
PDF .pdf أطروحة (متجه)
SVG .svg رسومات متجهة على الويب
JPEG .jpg صورة (لا يُنصح باستخدامها للرسومات)
TIFF .tiff طباعة
R
# Vector Graphics (Unlimited Clear Zoom)
ggsave("vector.svg", width = 8, height = 6)
ggsave("vector.pdf", width = 8, height = 6)


10. مثال كامل: رسوم بيانية احترافية بجودة النشر

فيما يلي مثال على مسار عمل كامل يربط بين جميع الموضوعات التي تم تناولها في هذا الدرس.

▶ مثال: مبيعات في 4 مدن — رسوم بيانية بجودة النشر

R 📖 للعرض فقط
# ============================================
# 4 City Sales: Publication-Quality Charts
# Features: Complete Customization from Default to Professional Level
# ============================================

library(ggplot2)
library(dplyr)
library(tidyr)
library(patchwork)
library(hrbrthemes)

# 1. Prepare data
sales_wide <- tibble(
  city = c("Beijing", "Shanghai", "Guangzhou", "Shenzhen"),
  Q1 = c(1000, 1500, 800, 1200),
  Q2 = c(1200, 1800, 900, 1400),
  Q3 = c(1100, 1700, 1000, 1300),
  Q4 = c(1500, 2000, 1200, 1600)
)

sales_long <- sales_wide |>
  pivot_longer(cols = -city, names_to = "quarter", values_to = "sales") |>
  mutate(
    total = sum(sales),
    pct = round(sales / total * 100, 1)
  )

# 2. Custom Themes
my_theme <- theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", size = 16, hjust = 0,
                              margin = margin(b = 5)),
    plot.subtitle = element_text(color = "gray40", size = 11,
                                 margin = margin(b = 15)),
    plot.caption = element_text(color = "gray50", size = 9,
                                hjust = 1, margin = margin(t = 10)),
    axis.title = element_text(size = 11),
    axis.text = element_text(size = 10, color = "gray30"),
    panel.grid.major = element_line(color = "gray90", linewidth = 0.3),
    panel.grid.minor = element_blank(),
    legend.position = "top",
    legend.title = element_text(size = 11),
    legend.text = element_text(size = 10),
    plot.background = element_rect(fill = "white", color = NA)
  )

# 3. Plot 1: Line Trend (Professional Edition)
p1 <- ggplot(sales_long, aes(x = quarter, y = sales, color = city, group = city)) +
  geom_line(linewidth = 1.2) +
  geom_point(size = 3.5, fill = "white", shape = 21, stroke = 1.5) +
  scale_color_brewer(palette = "Set1", name = "City") +
  scale_y_continuous(labels = scales::comma, expand = expansion(mult = 0.1)) +
  labs(
    title = "2024 Annual Quarterly Sales Trends",
    subtitle = "4 First-tier cities 4 Quarterly Sales Data",
    caption = "Data Source: Sales System | Chart: Analyst Team",
    x = NULL, y = "Sales (10,000 yuan)"
  ) +
  my_theme

# 4. Plot 2: Bar Chart Comparison (Professional Edition)
total_sales <- sales_wide |>
  mutate(total = Q1 + Q2 + Q3 + Q4) |>
  arrange(desc(total)) |>
  mutate(city = factor(city, levels = city))

p2 <- ggplot(total_sales, aes(x = city, y = total, fill = city)) +
  geom_col(width = 0.7) +
  geom_text(aes(label = scales::comma(total)), vjust = -0.5, size = 4) +
  scale_fill_brewer(palette = "Set1", guide = "none") +
  scale_y_continuous(labels = scales::comma,
                     expand = expansion(mult = c(0, 0.15))) +
  labs(
    title = "Annual Total Sales by City",
    subtitle = "Sort by total sales in descending order",
    x = NULL, y = "Total Sales (10,000 yuan)"
  ) +
  my_theme

# 5. Plot 3: Stacked Columns (Professional Edition)
sales_long_ordered <- sales_long |>
  left_join(total_sales |> select(city, total), by = "city") |>
  mutate(city = factor(city, levels = total_sales$city))

p3 <- ggplot(sales_long_ordered, aes(x = city, y = sales, fill = quarter)) +
  geom_col(position = "stack", width = 0.7) +
  scale_fill_brewer(palette = "YlGnBu", name = "Quarter") +
  labs(
    title = "Quarterly Sales Breakdown by City",
    subtitle = "Stacked bar chart showing quarterly contributions",
    x = NULL, y = "Sales (10,000 yuan)"
  ) +
  my_theme

# 6. Multi-Image Collage
combined <- (p1 / (p2 + p3)) +
  plot_annotation(
    title = "2024 4-City Comprehensive Sales Analysis",
    theme = theme(plot.title = element_text(face = "bold", size = 18, hjust = 0.5))
  )

print(combined)

# 7. Save Publication-Quality Images
ggsave("professional_report.png", combined,
       width = 14, height = 12, dpi = 300)
ggsave("professional_report.pdf", combined,
       width = 14, height = 12)
ggsave("professional_report.svg", combined,
       width = 14, height = 12)

cat("\n=== Publishing-quality charts have been saved ===\n")
cat("  - professional_report.png (PNG 300dpi)\n")
cat("  - professional_report.pdf (PDF Vector)\n")
cat("  - professional_report.svg (SVG Vector)\n")
91 سطر من الكود المنطقي (تجاوز الحد 40, للعرض فقط)

الناتج المتوقع: 3 مجموعات من الرسوم البيانية ذات الجودة المناسبة للنشر (رسم بياني خطي + رسم بياني عمودي + رسم بياني مكدس)، تتضمن عناوين باللغتين الصينية والإنجليزية، وأنظمة ألوان احترافية، وتسميات واضحة.



❓ أسئلة شائعة

س ما الفرق بين theme_minimal و theme_bw؟
ج theme_minimal Minimal (خلفية بيضاء، شبكة رمادية فاتحة)، theme_bw Black and White (مع حدود، شبكة واضحة).
س كيف يمكنني إزالة الشبكة الثانوية؟
ج theme(panel.grid.minor = element_blank()). هذا يجعل الصورة أكثر وضوحًا.
س أين يجب وضع المفتاح؟
ج يعتمد ذلك على مدى تعقيد المخطط. في حالة وجود متغير واحد أو متغيرين، استخدم bottom أو top؛ وفي حالة وجود 4 متغيرات أو أكثر، استخدم right؛ أما بالنسبة للمخططات الدائرية المضمنة داخل مخططات أخرى، فاستخدم c(0.5, 0.5) لتحديد موضع المفتاح.
س 300 نقطة في البوصة أم 150 نقطة في البوصة؟
ج 300 نقطة في البوصة للطباعة، و96–150 نقطة في البوصة للشاشات، أما ملفات PDF المتجهة فلا تتطلب تحديد دقة النقاط في البوصة. ggsave القيمة الافتراضية هي 300 نقطة في البوصة.
س كيف يمكنني تغيير الخط الصيني؟
ج theme_minimal(base_family = "SimHei") (ويندوز) أو "PingFang SC" (macOS) أو "WenQuanYi Zen Hei" (لينكس).

📖 ملخص


📝 تمارين

  1. تمرين أساسي: استخدم mtcars لإنشاء مخطط مبعثر لـ wt مقابل mpg، واستخدم الموضوعات الأربعة theme_minimal وtheme_bw وtheme_classic وtheme_void لمقارنة الاختلافات في المخططات الناتجة. التقط لقطات شاشة للمقارنة.

  2. تمرين أساسي: أنشئ مخططًا شريطيًّا واستخدم theme() لضبطه بدقة: ① اجعل العنوان بخط عريض، بحجم 16؛ ② أخفِ خطوط الشبكة الثانوية؛ ③ ضع المفتاح في الأسفل؛ ④ اضبط عنوان المحور الصادي بحيث يكون على بعد 10 بكسل من المحور.

  3. تمرين أساسي: ارسم الصورة نفسها باستخدام scale_color_brewer(palette = "Set1") وscale_color_brewer(palette = "Set2")، ثم التقط لقطات شاشة لمقارنة الاختلافات في الألوان.

  4. تمرين متقدم: قم بمحاكاة بيانات المبيعات لـ 4 مدن، وأنشئ مخططًا بيانيًّا كاملاً بجودة النشر مع التخصيصات التالية: ① سمة مخصصة ② تسميات «المختبرات» كاملة ③ نظام ألوان احترافي ④ حفظ بدقة عالية. احفظ لقطات شاشة لكل من العملية والنتائج.

  5. التحدي: استخدم ggthemes أو theme_economist() أو theme_wsj() لرسم صورة، وقارن الاختلافات مع theme_minimal() الافتراضي. احفظ الصورة بتنسيقي PNG وPDF (استخدم جهاز Cairo PDF لملف PDF لضمان دعم الأحرف الصينية).

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%