أقسام الوصول السريع (مربع البحث)

📰 آخر الأخبار

📊 الدرس الرابع: Matplotlib وSeaborn للتصور البياني

الدرس الرابع: Matplotlib وSeaborn للتصور البياني - شرح مفصل مع أمثلة عملية

📊 الدرس الرابع: Matplotlib وSeaborn للتصور البياني

🎯 الدرس الرابع من دورة Python للذكاء الاصطناعي | 📈 إتقان فن التصور البياني الاحترافي

📖 الدرس الرابع
⏱️ 90-120 دقيقة
🎓 متوسط-متقدم
📊 25+ نوع رسم بياني
4
Matplotlib وSeaborn للتصور البياني
Matplotlib وSeaborn: أقوى أدوات التصور البياني في Python

📊 الدرس الرابع: Matplotlib وSeaborn للتصور البياني

🎯 أهداف الدرس

  • فهم أساسيات التصور البياني وأهميته في علم البيانات
  • إتقان Matplotlib لإنشاء الرسوم البيانية الأساسية والمتقدمة
  • استخدام Seaborn للتصور الإحصائي الجميل والاحترافي
  • تخصيص الألوان والأنماط والتصاميم
  • إنشاء رسوم بيانية تفاعلية ومتحركة
  • أفضل ممارسات التصور البياني
  • تصدير الرسوم بجودة عالية للنشر
  • إنشاء لوحات معلومات شاملة

📋 المتطلبات السابقة

  • إكمال الدروس السابقة: Python وNumPy وPandas
  • فهم البيانات: أنواع البيانات والإحصائيات الأساسية
  • المكتبات مثبتة: pip install matplotlib seaborn
  • اختياري: pip install plotly (للرسوم التفاعلية)

🎨 لماذا التصور البياني مهم؟

التصور البياني ليس مجرد "رسوم جميلة" - إنه لغة عالمية لفهم البيانات وإيصال الأفكار المعقدة بطريقة بسيطة ومؤثرة.

أفضل ممارسات التصور البياني
أفضل ممارسات التصور البياني لإيصال الرسالة بوضوح

📊 حقائق مذهلة عن التصور البياني:

  • السرعة: الدماغ يعالج الصور 60,000 مرة أسرع من النص
  • الفهم: 90% من المعلومات المرسلة للدماغ بصرية
  • التذكر: الناس يتذكرون 65% من المعلومات البصرية بعد 3 أيام
  • الإقناع: الرسوم البيانية تزيد قوة الإقناع بنسبة 43%
  • الاستخدام: 99% من علماء البيانات يستخدمون التصور البياني

🛠️ مقدمة Matplotlib

Matplotlib هو المكتبة الأساسية للتصور البياني في Python. إنه يوفر تحكماً كاملاً في كل عنصر من عناصر الرسم البياني.

مقدمة Matplotlib
Matplotlib: المكتبة الأساسية للتصور البياني في Python

الإعداد الأساسي

import matplotlib.pyplot as plt import numpy as np import pandas as pd import seaborn as sns from datetime import datetime, timedelta # إعداد النمط العام plt.style.use('default') # أو 'seaborn', 'ggplot', 'bmh' plt.rcParams['font.size'] = 12 plt.rcParams['figure.figsize'] = (10, 6) plt.rcParams['font.family'] = 'DejaVu Sans' # إعداد Seaborn sns.set_palette("husl") sns.set_context("notebook", font_scale=1.2)

أول رسم بياني

# بيانات بسيطة للتجربة x = np.linspace(0, 10, 100) y = np.sin(x) # إنشاء الرسم البياني plt.figure(figsize=(10, 6)) plt.plot(x, y, linewidth=2, color='blue', label='sin(x)') plt.title('أول رسم بياني - دالة الجيب', fontsize=16, fontweight='bold') plt.xlabel('المحور السيني (x)', fontsize=12) plt.ylabel('المحور الصادي (y)', fontsize=12) plt.grid(True, alpha=0.3) plt.legend() plt.tight_layout() plt.show()

📈 أنواع الرسوم البيانية الأساسية

Matplotlib يدعم جميع أنواع الرسوم البيانية. دعنا نستكشف الأنواع الأساسية:

📊 الرسم الخطي (Line Plot)

الاستخدام: إظهار الاتجاهات عبر الزمن

# بيانات المبيعات الشهرية months = ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو'] sales = [15000, 18000, 22000, 19000, 25000, 28000] plt.figure(figsize=(10, 6)) plt.plot(months, sales, marker='o', linewidth=3, markersize=8) plt.title('مبيعات الشركة الشهرية', fontsize=16) plt.ylabel('المبيعات (ريال)') plt.xticks(rotation=45) plt.grid(True, alpha=0.3) plt.tight_layout() plt.show()

📊 الرسم العمودي (Bar Chart)

الاستخدام: مقارنة الفئات المختلفة

# بيانات الأقسام departments = ['المبيعات', 'التسويق', 'التطوير', 'الموارد البشرية'] employees = [45, 30, 60, 25] colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4'] plt.figure(figsize=(10, 6)) bars = plt.bar(departments, employees, color=colors, alpha=0.8) plt.title('عدد الموظفين في كل قسم', fontsize=16) plt.ylabel('عدد الموظفين') plt.xticks(rotation=45) # إضافة القيم على الأعمدة for bar, value in zip(bars, employees): plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 1, str(value), ha='center', va='bottom', fontweight='bold') plt.tight_layout() plt.show()

🥧 الرسم الدائري (Pie Chart)

الاستخدام: إظهار النسب والأجزاء من الكل

# بيانات الميزانية categories = ['الرواتب', 'التسويق', 'التطوير', 'الإدارة', 'أخرى'] budget = [40, 25, 20, 10, 5] colors = ['#FF9999', '#66B2FF', '#99FF99', '#FFCC99', '#FF99CC'] plt.figure(figsize=(10, 8)) wedges, texts, autotexts = plt.pie(budget, labels=categories, colors=colors, autopct='%1.1f%%', startangle=90, explode=(0.1, 0, 0, 0, 0)) plt.title('توزيع الميزانية السنوية', fontsize=16, fontweight='bold') # تحسين النصوص for autotext in autotexts: autotext.set_color('white') autotext.set_fontweight('bold') plt.axis('equal') plt.tight_layout() plt.show()

📊 الرسم المبعثر (Scatter Plot)

الاستخدام: إظهار العلاقة بين متغيرين

# بيانات العلاقة بين الخبرة والراتب np.random.seed(42) experience = np.random.randint(1, 20, 100) salary = 3000 + experience * 500 + np.random.normal(0, 1000, 100) plt.figure(figsize=(10, 6)) scatter = plt.scatter(experience, salary, alpha=0.6, s=60, c=experience, cmap='viridis') plt.colorbar(scatter, label='سنوات الخبرة') plt.title('العلاقة بين سنوات الخبرة والراتب', fontsize=16) plt.xlabel('سنوات الخبرة') plt.ylabel('الراتب (ريال)') plt.grid(True, alpha=0.3) plt.tight_layout() plt.show()

🎨 التخصيص المتقدم

القوة الحقيقية لـ Matplotlib تكمن في قدرته على التخصيص الكامل:

تخصيص الألوان والأنماط

# إنشاء بيانات متعددة x = np.linspace(0, 10, 100) y1 = np.sin(x) y2 = np.cos(x) y3 = np.sin(x + np.pi/4) # إنشاء رسم بياني متقدم fig, ax = plt.subplots(figsize=(12, 8)) # رسم الخطوط مع تخصيص متقدم line1 = ax.plot(x, y1, linewidth=3, color='#E74C3C', linestyle='-', label='sin(x)', alpha=0.8) line2 = ax.plot(x, y2, linewidth=3, color='#3498DB', linestyle='--', label='cos(x)', alpha=0.8) line3 = ax.plot(x, y3, linewidth=3, color='#2ECC71', linestyle='-.', label='sin(x+π/4)', alpha=0.8) # تخصيص العناوين والتسميات ax.set_title('مقارنة الدوال المثلثية', fontsize=20, fontweight='bold', pad=20, color='#2C3E50') ax.set_xlabel('المحور السيني (x)', fontsize=14, fontweight='bold') ax.set_ylabel('المحور الصادي (y)', fontsize=14, fontweight='bold') # تخصيص الشبكة ax.grid(True, linestyle=':', alpha=0.6, color='gray') ax.set_facecolor('#F8F9FA') # تخصيص الأسطورة legend = ax.legend(loc='upper right', frameon=True, shadow=True, fancybox=True, fontsize=12) legend.get_frame().set_facecolor('#FFFFFF') legend.get_frame().set_alpha(0.9) # تخصيص المحاور ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['left'].set_linewidth(2) ax.spines['bottom'].set_linewidth(2) # إضافة تأثيرات بصرية ax.fill_between(x, y1, alpha=0.2, color='#E74C3C') ax.fill_between(x, y2, alpha=0.2, color='#3498DB') plt.tight_layout() plt.show()

الرسوم المتعددة (Subplots)

# إنشاء بيانات للتجربة np.random.seed(42) data1 = np.random.normal(100, 15, 1000) data2 = np.random.exponential(2, 1000) x = np.linspace(0, 10, 100) y = np.sin(x) + np.random.normal(0, 0.1, 100) # إنشاء شبكة من الرسوم البيانية fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 12)) fig.suptitle('لوحة معلومات شاملة', fontsize=20, fontweight='bold', y=0.98) # الرسم الأول: هيستوجرام ax1.hist(data1, bins=30, color='#3498DB', alpha=0.7, edgecolor='black') ax1.set_title('توزيع البيانات الطبيعي', fontweight='bold') ax1.set_xlabel('القيم') ax1.set_ylabel('التكرار') ax1.grid(True, alpha=0.3) # الرسم الثاني: رسم صندوقي box_data = [data1, data2, np.random.normal(80, 20, 1000)] box_plot = ax2.boxplot(box_data, labels=['مجموعة 1', 'مجموعة 2', 'مجموعة 3'], patch_artist=True) colors = ['#E74C3C', '#2ECC71', '#F39C12'] for patch, color in zip(box_plot['boxes'], colors): patch.set_facecolor(color) patch.set_alpha(0.7) ax2.set_title('مقارنة التوزيعات', fontweight='bold') ax2.set_ylabel('القيم') ax2.grid(True, alpha=0.3) # الرسم الثالث: رسم مبعثر مع خط الاتجاه ax3.scatter(x, y, alpha=0.6, color='#9B59B6', s=50) z = np.polyfit(x, y, 1) p = np.poly1d(z) ax3.plot(x, p(x), color='#E74C3C', linewidth=2, linestyle='--') ax3.set_title('البيانات مع خط الاتجاه', fontweight='bold') ax3.set_xlabel('المحور السيني') ax3.set_ylabel('المحور الصادي') ax3.grid(True, alpha=0.3) # الرسم الرابع: رسم دائري sizes = [30, 25, 20, 15, 10] labels = ['فئة أ', 'فئة ب', 'فئة ج', 'فئة د', 'فئة هـ'] colors_pie = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7'] wedges, texts, autotexts = ax4.pie(sizes, labels=labels, colors=colors_pie, autopct='%1.1f%%', startangle=90) ax4.set_title('توزيع الفئات', fontweight='bold') plt.tight_layout() plt.show()
دليل Matplotlib السريع
دليل Matplotlib السريع - جميع أنواع الرسوم البيانية

🌊 مقدمة Seaborn

Seaborn مبني على Matplotlib ويوفر واجهة أبسط وأجمل للتصور الإحصائي:

مقدمة Seaborn
Seaborn: التصور الإحصائي الجميل والبسيط

إنشاء بيانات تجريبية شاملة

# إنشاء بيانات شاملة للتجربة np.random.seed(42) n_samples = 1000 # بيانات الموظفين employees_data = { 'الاسم': [f'موظف_{i}' for i in range(1, n_samples + 1)], 'القسم': np.random.choice(['المبيعات', 'التسويق', 'التطوير', 'الموارد البشرية', 'المالية'], n_samples), 'العمر': np.random.randint(22, 65, n_samples), 'سنوات_الخبرة': np.random.randint(0, 20, n_samples), 'الراتب': np.random.normal(8000, 2500, n_samples), 'تقييم_الأداء': np.random.randint(60, 100, n_samples), 'الجنس': np.random.choice(['ذكر', 'أنثى'], n_samples), 'المدينة': np.random.choice(['الرياض', 'جدة', 'الدمام', 'مكة', 'المدينة'], n_samples), 'مستوى_التعليم': np.random.choice(['ثانوي', 'بكالوريوس', 'ماجستير', 'دكتوراه'], n_samples, p=[0.1, 0.6, 0.25, 0.05]) } # تحسين البيانات لتكون أكثر واقعية for i in range(n_samples): # ربط الراتب بالخبرة والتعليم experience_bonus = employees_data['سنوات_الخبرة'][i] * 200 education_bonus = {'ثانوي': 0, 'بكالوريوس': 1000, 'ماجستير': 2000, 'دكتوراه': 3500}[employees_data['مستوى_التعليم'][i]] employees_data['الراتب'][i] = max(3000, employees_data['الراتب'][i] + experience_bonus + education_bonus) # ربط تقييم الأداء بالخبرة if employees_data['سنوات_الخبرة'][i] > 10: employees_data['تقييم_الأداء'][i] = min(100, employees_data['تقييم_الأداء'][i] + 10) df = pd.DataFrame(employees_data) print(f"تم إنشاء بيانات {len(df)} موظف للتجربة") print(f"أول 5 صفوف: {df.head()}")

الرسوم الإحصائية الأساسية

# 1. رسم التوزيع (Distribution Plot) plt.figure(figsize=(15, 10)) # الرسم الأول: توزيع الرواتب plt.subplot(2, 3, 1) sns.histplot(data=df, x='الراتب', kde=True, color='skyblue') plt.title('توزيع الرواتب', fontweight='bold') plt.xlabel('الراتب (ريال)') # الرسم الثاني: رسم صندوقي للرواتب حسب القسم plt.subplot(2, 3, 2) sns.boxplot(data=df, x='القسم', y='الراتب', palette='Set2') plt.title('الرواتب حسب القسم', fontweight='bold') plt.xticks(rotation=45) # الرسم الثالث: رسم كمان للأعمار حسب الجنس plt.subplot(2, 3, 3) sns.violinplot(data=df, x='الجنس', y='العمر', palette='pastel') plt.title('توزيع الأعمار حسب الجنس', fontweight='bold') # الرسم الرابع: رسم مبعثر للعلاقة بين الخبرة والراتب plt.subplot(2, 3, 4) sns.scatterplot(data=df, x='سنوات_الخبرة', y='الراتب', hue='القسم', size='تقييم_الأداء', alpha=0.7) plt.title('العلاقة بين الخبرة والراتب', fontweight='bold') # الرسم الخامس: رسم عد للأقسام حسب المدينة plt.subplot(2, 3, 5) sns.countplot(data=df, x='المدينة', hue='القسم', palette='viridis') plt.title('توزيع الأقسام حسب المدينة', fontweight='bold') plt.xticks(rotation=45) # الرسم السادس: رسم خطي لمتوسط الراتب حسب العمر plt.subplot(2, 3, 6) age_salary = df.groupby('العمر')['الراتب'].mean().reset_index() sns.lineplot(data=age_salary, x='العمر', y='الراتب', marker='o') plt.title('متوسط الراتب حسب العمر', fontweight='bold') plt.tight_layout() plt.show()

خريطة الحرارة (Heatmap)

# إنشاء مصفوفة الارتباط numeric_cols = ['العمر', 'سنوات_الخبرة', 'الراتب', 'تقييم_الأداء'] correlation_matrix = df[numeric_cols].corr() # رسم خريطة الحرارة plt.figure(figsize=(10, 8)) mask = np.triu(np.ones_like(correlation_matrix, dtype=bool)) sns.heatmap(correlation_matrix, mask=mask, annot=True, cmap='RdYlBu_r', center=0, square=True, fmt='.2f', cbar_kws={'shrink': 0.8}) plt.title('مصفوفة الارتباط بين المتغيرات الرقمية', fontsize=16, fontweight='bold', pad=20) plt.tight_layout() plt.show() # تحليل النتائج print("تحليل الارتباطات:") print("=" * 30) for i in range(len(correlation_matrix.columns)): for j in range(i+1, len(correlation_matrix.columns)): corr_value = correlation_matrix.iloc[i, j] var1 = correlation_matrix.columns[i] var2 = correlation_matrix.columns[j] if abs(corr_value) > 0.5: strength = "قوي" if abs(corr_value) > 0.7 else "متوسط" direction = "طردي" if corr_value > 0 else "عكسي" print(f"{var1} و {var2}: ارتباط {strength} {direction} ({corr_value:.2f})")

الرسوم المتقدمة

# 1. رسم الزوج (Pair Plot) plt.figure(figsize=(12, 10)) pair_plot = sns.pairplot(df[numeric_cols + ['القسم']], hue='القسم', diag_kind='kde', plot_kws={'alpha': 0.6}) pair_plot.fig.suptitle('مصفوفة الرسوم المزدوجة', y=1.02, fontsize=16, fontweight='bold') plt.show() # 2. رسم التوزيع المشترك plt.figure(figsize=(12, 8)) sns.jointplot(data=df, x='سنوات_الخبرة', y='الراتب', kind='reg', height=8, color='coral') plt.suptitle('التوزيع المشترك: الخبرة والراتب', y=1.02, fontsize=16, fontweight='bold') plt.show() # 3. رسم الكثافة ثنائي الأبعاد plt.figure(figsize=(10, 8)) plt.subplot(2, 2, 1) sns.kdeplot(data=df, x='العمر', y='الراتب', cmap='Blues', fill=True) plt.title('كثافة العمر والراتب') plt.subplot(2, 2, 2) sns.kdeplot(data=df, x='سنوات_الخبرة', y='تقييم_الأداء', cmap='Reds', fill=True) plt.title('كثافة الخبرة والأداء') plt.subplot(2, 2, 3) sns.regplot(data=df, x='العمر', y='الراتب', scatter_kws={'alpha': 0.5}) plt.title('الانحدار: العمر والراتب') plt.subplot(2, 2, 4) sns.residplot(data=df, x='سنوات_الخبرة', y='الراتب', color='green') plt.title('بواقي الانحدار') plt.tight_layout() plt.show()
دليل التصور البياني
دليل شامل لأنواع التصور البياني المختلفة

🎨 التخصيص المتقدم في Seaborn

Seaborn يوفر إمكانيات تخصيص قوية مع سهولة الاستخدام:

الأنماط والألوان المخصصة

# إنشاء نمط مخصص custom_style = { 'axes.facecolor': '#F8F9FA', 'axes.edgecolor': '#2C3E50', 'axes.linewidth': 2, 'axes.grid': True, 'grid.color': '#BDC3C7', 'grid.alpha': 0.6, 'xtick.color': '#2C3E50', 'ytick.color': '#2C3E50', 'text.color': '#2C3E50', 'font.size': 12, 'axes.titlesize': 16, 'axes.labelsize': 14 } # تطبيق النمط المخصص with plt.rc_context(custom_style): # إنشاء لوحة ألوان مخصصة custom_palette = ['#E74C3C', '#3498DB', '#2ECC71', '#F39C12', '#9B59B6'] sns.set_palette(custom_palette) # رسم متقدم مع التخصيص fig, axes = plt.subplots(2, 2, figsize=(16, 12)) fig.suptitle('لوحة معلومات مخصصة', fontsize=20, fontweight='bold', y=0.98) # الرسم الأول: رسم كمان متقدم sns.violinplot(data=df, x='القسم', y='الراتب', inner='quart', palette=custom_palette, ax=axes[0,0]) axes[0,0].set_title('توزيع الرواتب حسب القسم', fontweight='bold') axes[0,0].tick_params(axis='x', rotation=45) # الرسم الثاني: رسم شريطي متقدم dept_avg = df.groupby('القسم')['تقييم_الأداء'].mean().sort_values(ascending=False) sns.barplot(x=dept_avg.values, y=dept_avg.index, palette=custom_palette, ax=axes[0,1]) axes[0,1].set_title('متوسط تقييم الأداء حسب القسم', fontweight='bold') axes[0,1].set_xlabel('متوسط التقييم') # الرسم الثالث: رسم نقطي متقدم sns.stripplot(data=df, x='مستوى_التعليم', y='الراتب', hue='الجنس', size=8, alpha=0.7, ax=axes[1,0]) axes[1,0].set_title('الرواتب حسب التعليم والجنس', fontweight='bold') axes[1,0].tick_params(axis='x', rotation=45) # الرسم الرابع: رسم سداسي axes[1,1].hexbin(df['العمر'], df['الراتب'], gridsize=20, cmap='YlOrRd') axes[1,1].set_title('الكثافة السداسية: العمر والراتب', fontweight='bold') axes[1,1].set_xlabel('العمر') axes[1,1].set_ylabel('الراتب') plt.tight_layout() plt.show()

الرسوم التفاعلية مع Plotly

# تثبيت Plotly إذا لم يكن مثبتاً # pip install plotly import plotly.express as px import plotly.graph_objects as go from plotly.subplots import make_subplots # 1. رسم مبعثر تفاعلي fig_scatter = px.scatter(df, x='سنوات_الخبرة', y='الراتب', color='القسم', size='تقييم_الأداء', hover_data=['العمر', 'المدينة'], title='العلاقة التفاعلية بين الخبرة والراتب') fig_scatter.update_layout( font=dict(size=14), title_font_size=18, width=800, height=600 ) # عرض الرسم (في Jupyter Notebook) # fig_scatter.show() # 2. رسم خطي تفاعلي للاتجاهات monthly_data = { 'الشهر': ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو'], 'المبيعات': [15000, 18000, 22000, 19000, 25000, 28000], 'الأرباح': [3000, 4500, 5500, 4000, 6200, 7000], 'العملاء_الجدد': [120, 150, 180, 160, 200, 220] } monthly_df = pd.DataFrame(monthly_data) fig_lines = make_subplots( rows=2, cols=2, subplot_titles=('المبيعات الشهرية', 'الأرباح الشهرية', 'العملاء الجدد', 'مقارنة شاملة'), specs=[[{'secondary_y': False}, {'secondary_y': False}], [{'secondary_y': False}, {'secondary_y': True}]] ) # إضافة الرسوم fig_lines.add_trace( go.Scatter(x=monthly_df['الشهر'], y=monthly_df['المبيعات'], mode='lines+markers', name='المبيعات', line=dict(color='#E74C3C')), row=1, col=1 ) fig_lines.add_trace( go.Scatter(x=monthly_df['الشهر'], y=monthly_df['الأرباح'], mode='lines+markers', name='الأرباح', line=dict(color='#2ECC71')), row=1, col=2 ) fig_lines.add_trace( go.Bar(x=monthly_df['الشهر'], y=monthly_df['العملاء_الجدد'], name='العملاء الجدد', marker_color='#3498DB'), row=2, col=1 ) # رسم مقارن fig_lines.add_trace( go.Scatter(x=monthly_df['الشهر'], y=monthly_df['المبيعات'], mode='lines', name='المبيعات', line=dict(color='#E74C3C')), row=2, col=2 ) fig_lines.add_trace( go.Scatter(x=monthly_df['الشهر'], y=monthly_df['العملاء_الجدد'], mode='lines', name='العملاء الجدد', line=dict(color='#3498DB'), yaxis='y2'), row=2, col=2, secondary_y=True ) fig_lines.update_layout(height=800, title_text="لوحة معلومات تفاعلية") # fig_lines.show() print("تم إنشاء الرسوم التفاعلية! (استخدم fig.show() في Jupyter Notebook)")

📊 مثال عملي شامل: تحليل بيانات المبيعات

الآن سنطبق جميع ما تعلمناه في مثال واقعي ومعقد:

إنشاء بيانات مبيعات شاملة

# إنشاء بيانات مبيعات واقعية np.random.seed(42) # إنشاء بيانات زمنية start_date = datetime(2023, 1, 1) end_date = datetime(2024, 12, 31) date_range = pd.date_range(start=start_date, end=end_date, freq='D') # إنشاء بيانات المبيعات اليومية sales_data = [] base_sales = 10000 for date in date_range: # تأثير الموسمية month_factor = 1 + 0.3 * np.sin(2 * np.pi * date.month / 12) # تأثير يوم الأسبوع weekday_factor = 1.2 if date.weekday() < 5 else 0.8 # أيام العمل أعلى # تأثير الأعياد والمناسبات holiday_factor = 1.5 if date.month in [12, 1, 6, 7] else 1.0 # اتجاه النمو growth_factor = 1 + (date - start_date).days * 0.0001 # مبيعات اليوم daily_sales = base_sales * month_factor * weekday_factor * holiday_factor * growth_factor daily_sales += np.random.normal(0, daily_sales * 0.1) # ضوضاء عشوائية # بيانات إضافية customers = int(daily_sales / np.random.uniform(80, 120)) avg_order = daily_sales / customers if customers > 0 else 0 sales_data.append({ 'التاريخ': date, 'المبيعات': max(0, daily_sales), 'عدد_العملاء': customers, 'متوسط_الطلب': avg_order, 'اليوم': date.strftime('%A'), 'الشهر': date.strftime('%B'), 'السنة': date.year, 'الربع': f'Q{(date.month-1)//3 + 1}', 'نهاية_الأسبوع': date.weekday() >= 5 }) sales_df = pd.DataFrame(sales_data) sales_df['المبيعات'] = sales_df['المبيعات'].round(2) sales_df['متوسط_الطلب'] = sales_df['متوسط_الطلب'].round(2) print(f"تم إنشاء بيانات مبيعات لـ {len(sales_df)} يوم") print(f"إجمالي المبيعات: {sales_df['المبيعات'].sum():,.2f} ريال") print(f"متوسط المبيعات اليومية: {sales_df['المبيعات'].mean():,.2f} ريال")

تحليل بصري شامل للمبيعات

# إنشاء لوحة معلومات شاملة للمبيعات fig = plt.figure(figsize=(20, 16)) gs = fig.add_gridspec(4, 4, hspace=0.3, wspace=0.3) # 1. اتجاه المبيعات عبر الزمن ax1 = fig.add_subplot(gs[0, :2]) ax1.plot(sales_df['التاريخ'], sales_df['المبيعات'], linewidth=1, alpha=0.7, color='#3498DB') ax1.plot(sales_df['التاريخ'], sales_df['المبيعات'].rolling(30).mean(), linewidth=3, color='#E74C3C', label='المتوسط المتحرك (30 يوم)') ax1.set_title('اتجاه المبيعات عبر الزمن', fontsize=16, fontweight='bold') ax1.set_ylabel('المبيعات (ريال)') ax1.legend() ax1.grid(True, alpha=0.3) # 2. المبيعات الشهرية ax2 = fig.add_subplot(gs[0, 2:]) monthly_sales = sales_df.groupby('الشهر')['المبيعات'].sum().reindex([ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]) bars = ax2.bar(range(len(monthly_sales)), monthly_sales.values, color=plt.cm.viridis(np.linspace(0, 1, 12))) ax2.set_title('إجمالي المبيعات الشهرية', fontsize=16, fontweight='bold') ax2.set_ylabel('المبيعات (ريال)') ax2.set_xticks(range(12)) ax2.set_xticklabels(['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'], rotation=45) # 3. المبيعات حسب يوم الأسبوع ax3 = fig.add_subplot(gs[1, :2]) weekday_sales = sales_df.groupby('اليوم')['المبيعات'].mean().reindex([ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ]) weekday_names = ['الإثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت', 'الأحد'] colors = ['#E74C3C' if day in ['Saturday', 'Sunday'] else '#3498DB' for day in weekday_sales.index] ax3.bar(weekday_names, weekday_sales.values, color=colors, alpha=0.8) ax3.set_title('متوسط المبيعات حسب يوم الأسبوع', fontsize=16, fontweight='bold') ax3.set_ylabel('متوسط المبيعات (ريال)') ax3.tick_params(axis='x', rotation=45) # 4. توزيع المبيعات ax4 = fig.add_subplot(gs[1, 2:]) ax4.hist(sales_df['المبيعات'], bins=50, alpha=0.7, color='#2ECC71', edgecolor='black') ax4.axvline(sales_df['المبيعات'].mean(), color='#E74C3C', linestyle='--', linewidth=2, label=f'المتوسط: {sales_df["المبيعات"].mean():.0f}') ax4.axvline(sales_df['المبيعات'].median(), color='#F39C12', linestyle='--', linewidth=2, label=f'الوسيط: {sales_df["المبيعات"].median():.0f}') ax4.set_title('توزيع المبيعات اليومية', fontsize=16, fontweight='bold') ax4.set_xlabel('المبيعات (ريال)') ax4.set_ylabel('التكرار') ax4.legend() # 5. العلاقة بين عدد العملاء ومتوسط الطلب ax5 = fig.add_subplot(gs[2, :2]) scatter = ax5.scatter(sales_df['عدد_العملاء'], sales_df['متوسط_الطلب'], c=sales_df['المبيعات'], cmap='viridis', alpha=0.6, s=30) ax5.set_title('العلاقة بين عدد العملاء ومتوسط الطلب', fontsize=16, fontweight='bold') ax5.set_xlabel('عدد العملاء') ax5.set_ylabel('متوسط الطلب (ريال)') plt.colorbar(scatter, ax=ax5, label='المبيعات') # 6. المبيعات الربعية ax6 = fig.add_subplot(gs[2, 2:]) quarterly_sales = sales_df.groupby(['السنة', 'الربع'])['المبيعات'].sum().reset_index() quarterly_sales['الفترة'] = quarterly_sales['السنة'].astype(str) + '-' + quarterly_sales['الربع'] ax6.plot(quarterly_sales['الفترة'], quarterly_sales['المبيعات'], marker='o', linewidth=3, markersize=8, color='#9B59B6') ax6.set_title('المبيعات الربعية', fontsize=16, fontweight='bold') ax6.set_ylabel('المبيعات (ريال)') ax6.tick_params(axis='x', rotation=45) ax6.grid(True, alpha=0.3) # 7. مقارنة أيام العمل ونهاية الأسبوع ax7 = fig.add_subplot(gs[3, :2]) weekend_comparison = sales_df.groupby('نهاية_الأسبوع')['المبيعات'].agg(['mean', 'std']) categories = ['أيام العمل', 'نهاية الأسبوع'] means = [weekend_comparison.loc[False, 'mean'], weekend_comparison.loc[True, 'mean']] stds = [weekend_comparison.loc[False, 'std'], weekend_comparison.loc[True, 'std']] bars = ax7.bar(categories, means, yerr=stds, capsize=5, color=['#3498DB', '#E74C3C'], alpha=0.8) ax7.set_title('مقارنة المبيعات: أيام العمل vs نهاية الأسبوع', fontsize=16, fontweight='bold') ax7.set_ylabel('متوسط المبيعات (ريال)') # إضافة القيم على الأعمدة for bar, mean in zip(bars, means): ax7.text(bar.get_x() + bar.get_width()/2, bar.get_height() + bar.get_height()*0.01, f'{mean:.0f}', ha='center', va='bottom', fontweight='bold') # 8. خريطة حرارة للمبيعات (الشهر × يوم الأسبوع) ax8 = fig.add_subplot(gs[3, 2:]) pivot_data = sales_df.pivot_table(values='المبيعات', index='الشهر', columns='اليوم', aggfunc='mean') # إعادة ترتيب الأعمدة والصفوف month_order = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] weekday_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] pivot_data = pivot_data.reindex(month_order).reindex(columns=weekday_order) im = ax8.imshow(pivot_data.values, cmap='YlOrRd', aspect='auto') ax8.set_title('خريطة حرارة: المبيعات حسب الشهر ويوم الأسبوع', fontsize=16, fontweight='bold') ax8.set_xticks(range(7)) ax8.set_xticklabels(['الإثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت', 'الأحد'], rotation=45) ax8.set_yticks(range(12)) ax8.set_yticklabels(['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر']) # إضافة شريط الألوان cbar = plt.colorbar(im, ax=ax8, shrink=0.8) cbar.set_label('متوسط المبيعات (ريال)') plt.suptitle('لوحة معلومات شاملة لتحليل المبيعات', fontsize=24, fontweight='bold', y=0.98) plt.show()

تحليل إحصائي متقدم

# تحليل إحصائي شامل للمبيعات print("📊 التحليل الإحصائي الشامل للمبيعات") print("=" * 60) # 1. الإحصائيات الأساسية print(" 1. الإحصائيات الأساسية:") print(f"إجمالي المبيعات: {sales_df['المبيعات'].sum():,.2f} ريال") print(f"متوسط المبيعات اليومية: {sales_df['المبيعات'].mean():,.2f} ريال") print(f"الوسيط: {sales_df['المبيعات'].median():,.2f} ريال") print(f"الانحراف المعياري: {sales_df['المبيعات'].std():,.2f} ريال") print(f"أعلى مبيعات يومية: {sales_df['المبيعات'].max():,.2f} ريال") print(f"أقل مبيعات يومية: {sales_df['المبيعات'].min():,.2f} ريال") # 2. تحليل النمو sales_df['المبيعات_المتحركة'] = sales_df['المبيعات'].rolling(30).mean() first_month_avg = sales_df.head(30)['المبيعات'].mean() last_month_avg = sales_df.tail(30)['المبيعات'].mean() growth_rate = ((last_month_avg - first_month_avg) / first_month_avg) * 100 print(f" 2. تحليل النمو:") print(f"متوسط أول شهر: {first_month_avg:,.2f} ريال") print(f"متوسط آخر شهر: {last_month_avg:,.2f} ريال") print(f"معدل النمو: {growth_rate:.1f}%") # 3. تحليل الموسمية print(f" 3. تحليل الموسمية:") seasonal_analysis = sales_df.groupby('الشهر')['المبيعات'].agg(['mean', 'std']).round(2) best_month = seasonal_analysis['mean'].idxmax() worst_month = seasonal_analysis['mean'].idxmin() print(f"أفضل شهر: {best_month} ({seasonal_analysis.loc[best_month, 'mean']:,.2f} ريال)") print(f"أسوأ شهر: {worst_month} ({seasonal_analysis.loc[worst_month, 'mean']:,.2f} ريال)") # 4. تحليل أيام الأسبوع print(f" 4. تحليل أيام الأسبوع:") weekday_analysis = sales_df.groupby('اليوم')['المبيعات'].mean().round(2) best_day = weekday_analysis.idxmax() worst_day = weekday_analysis.idxmin() print(f"أفضل يوم: {best_day} ({weekday_analysis[best_day]:,.2f} ريال)") print(f"أسوأ يوم: {worst_day} ({weekday_analysis[worst_day]:,.2f} ريال)") # 5. تحليل التقلبات print(f" 5. تحليل التقلبات:") volatility = (sales_df['المبيعات'].std() / sales_df['المبيعات'].mean()) * 100 print(f"معامل التقلب: {volatility:.1f}%") # تحديد الأيام الاستثنائية q1 = sales_df['المبيعات'].quantile(0.25) q3 = sales_df['المبيعات'].quantile(0.75) iqr = q3 - q1 outliers = sales_df[(sales_df['المبيعات'] < q1 - 1.5*iqr) | (sales_df['المبيعات'] > q3 + 1.5*iqr)] print(f"عدد الأيام الاستثنائية: {len(outliers)} يوم ({len(outliers)/len(sales_df)*100:.1f}%)") # 6. تحليل الارتباطات print(f" 6. تحليل الارتباطات:") correlations = sales_df[['المبيعات', 'عدد_العملاء', 'متوسط_الطلب']].corr() print(f"الارتباط بين المبيعات وعدد العملاء: {correlations.loc['المبيعات', 'عدد_العملاء']:.3f}") print(f"الارتباط بين المبيعات ومتوسط الطلب: {correlations.loc['المبيعات', 'متوسط_الطلب']:.3f}") # 7. توقعات بسيطة print(f" 7. توقعات بسيطة (بناءً على الاتجاه الحالي):") trend = np.polyfit(range(len(sales_df)), sales_df['المبيعات'], 1) next_month_prediction = trend[0] * (len(sales_df) + 30) + trend[1] print(f"توقع متوسط المبيعات للشهر القادم: {next_month_prediction:,.2f} ريال")

💡 أفضل ممارسات التصور البياني

🎯 قواعد التصور البياني الفعال:

  • اختر النوع المناسب: خطي للاتجاهات، عمودي للمقارنات، دائري للنسب
  • ابدأ من الصفر: لا تقطع المحاور إلا لسبب مبرر
  • استخدم الألوان بذكاء: ألوان متناسقة ومعبرة
  • أضف السياق: عناوين واضحة وتسميات مفهومة
  • تجنب الفوضى: لا تكدس الرسم بمعلومات زائدة
  • اجعله تفاعلياً: استخدم Plotly للرسوم التفاعلية

حفظ وتصدير الرسوم البيانية

# إنشاء رسم بياني للحفظ plt.figure(figsize=(12, 8)) plt.plot(sales_df['التاريخ'], sales_df['المبيعات'].rolling(7).mean(), linewidth=3, color='#E74C3C', label='المتوسط المتحرك (7 أيام)') plt.fill_between(sales_df['التاريخ'], sales_df['المبيعات'].rolling(7).mean() - sales_df['المبيعات'].rolling(7).std(), sales_df['المبيعات'].rolling(7).mean() + sales_df['المبيعات'].rolling(7).std(), alpha=0.3, color='#E74C3C') plt.title('اتجاه المبيعات مع نطاق الثقة', fontsize=18, fontweight='bold', pad=20) plt.xlabel('التاريخ', fontsize=14) plt.ylabel('المبيعات (ريال)', fontsize=14) plt.legend(fontsize=12) plt.grid(True, alpha=0.3) plt.tight_layout() # حفظ بتنسيقات مختلفة plt.savefig('sales_trend.png', dpi=300, bbox_inches='tight', facecolor='white', edgecolor='none') plt.savefig('sales_trend.pdf', bbox_inches='tight', facecolor='white', edgecolor='none') plt.savefig('sales_trend.svg', bbox_inches='tight', facecolor='white', edgecolor='none') print("تم حفظ الرسم البياني بتنسيقات PNG وPDF وSVG") # حفظ رسم Seaborn plt.figure(figsize=(10, 8)) correlation_plot = sns.heatmap(sales_df[['المبيعات', 'عدد_العملاء', 'متوسط_الطلب']].corr(), annot=True, cmap='RdYlBu_r', center=0, square=True, cbar_kws={'shrink': 0.8}) plt.title('مصفوفة الارتباط', fontsize=16, fontweight='bold') plt.tight_layout() plt.savefig('correlation_heatmap.png', dpi=300, bbox_inches='tight') plt.show() print("تم حفظ خريطة الحرارة")

🎯 تمارين عملية

تمرين 1: تحليل بيانات الطقس

أنشئ وحلل بيانات الطقس لمدة سنة:

  • درجات الحرارة اليومية والرطوبة
  • رسم خطي للاتجاهات الموسمية
  • خريطة حرارة للشهر × درجة الحرارة
  • رسم مبعثر للعلاقة بين الحرارة والرطوبة

تمرين 2: تحليل بيانات الأسهم

حلل أداء محفظة أسهم:

  • رسم خطي لأسعار 5 أسهم مختلفة
  • رسم شمعي (Candlestick) لسهم واحد
  • حساب وعرض المتوسطات المتحركة
  • تحليل التقلبات والمخاطر

تمرين 3: لوحة معلومات تفاعلية

أنشئ لوحة معلومات شاملة:

  • استخدم Plotly لإنشاء رسوم تفاعلية
  • اربط عدة رسوم بيانية معاً
  • أضف فلاتر وخيارات تفاعلية
  • صدر اللوحة كملف HTML
⚠️ أخطاء شائعة يجب تجنبها:
  • الرسوم المزدحمة: تجنب وضع معلومات كثيرة في رسم واحد
  • الألوان المتضاربة: استخدم لوحات ألوان متناسقة
  • المحاور المضللة: لا تقطع المحاور بدون مبرر
  • عدم وضوح التسميات: تأكد من وضوح جميع النصوص
  • تجاهل السياق: أضف عناوين وتفسيرات واضحة

📝 ملخص الدرس

في هذا الدرس الشامل تعلمنا:

  • أساسيات التصور البياني: أهميته وأفضل الممارسات
  • Matplotlib الأساسي: الرسوم الخطية والعمودية والدائرية
  • التخصيص المتقدم: الألوان والأنماط والتأثيرات
  • الرسوم المتعددة: Subplots ولوحات المعلومات
  • Seaborn الإحصائي: الرسوم الإحصائية الجميلة
  • خرائط الحرارة: تصور الارتباطات والأنماط
  • الرسوم التفاعلية: Plotly للتفاعل المتقدم
  • مثال عملي شامل: تحليل بيانات المبيعات
  • الحفظ والتصدير: تنسيقات عالية الجودة
  • أفضل الممارسات: قواعد التصور الفعال

➡️ الدرس التالي

في الدرس التالي سنتعلم Scikit-learn الأساسيات:

  • مقدمة التعلم الآلي والمفاهيم الأساسية
  • تحضير البيانات والمعالجة المسبقة
  • خوارزميات التصنيف والانحدار
  • تقييم النماذج ومقاييس الأداء
  • التحقق المتقاطع وضبط المعاملات
  • مشاريع عملية في التعلم الآلي

🎯 إكمال الدرس

بإكمال هذا الدرس والتمارين العملية، ستكون مؤهلاً لإنشاء تصورات بيانية احترافية وتفاعلية في مشاريع علم البيانات

⚖️ حقوق النشر

© 2025 الذكاء الاصطناعي بالعربي. جميع الحقوق محفوظة

إخلاء المسؤولية: هذا المحتوى للأغراض التعليمية والإعلامية فقط

تعليقات