مشروع مصغر: بناء لوحة معلومات (Dashboard) بسيطة باستخدام بايثون لبيانات طقس

دقائق القراءة: 6

مشروع مصغر: بناء لوحة معلومات بسيطة باستخدام بايثون لبيانات طقس

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

عند تنفيذ هذا السيناريو باستخدام Python، فإنك تبني أساساً عملياً يمكن تطويره لاحقاً إلى نظام أكبر يعمل على بيانات لحظية أو موزعة عبر Spark وHadoop عند تضخم حجم السجلات.

سنفترض وجود ملف طقس يومي يحتوي على التاريخ، المدينة، درجات الحرارة، الرطوبة، سرعة الرياح، وحالة الطقس. الفكرة ليست فقط قراءة الملف، بل تحويله إلى لوحة تمنح المستخدم إجابات سريعة: ما متوسط الحرارة؟ متى حدثت أعلى قراءة؟ وهل توجد أنماط زمنية واضحة؟

فهم بنية البيانات قبل بدء البرمجة

قبل أي رسم بياني، يجب فهم شكل الجدول ومصدره. إذا كنت قد تابعت مقال مكتبة Pandas (1): قراءة واستدعاء البيانات من ملفات CSV و Excel برمجياً فستعرف أن جودة التحليل تبدأ من قراءة صحيحة للملف. أما فهم الأعمدة وأنواعها فيرتبط مباشرة بما شرحناه في مكتبة Pandas (2): استكشاف هيكل البيانات وفهم DataFrame و Series.

لنموذج بيانات الطقس، من الأفضل أن يتضمن الجدول الأعمدة التالية:

  • عمود date بصيغة تاريخ.
  • عمود city لتحديد الموقع.
  • أعمدة رقمية مثل temperature وhumidity وwind_speed.
  • عمود وصفي مثل weather_condition.

هذا التنظيم يمكّنك لاحقاً من تنفيذ التصفية، التجميع، وبناء مؤشرات أداء سريعة داخل اللوحة دون إعادة هيكلة البيانات في كل مرة.

قراءة البيانات وتنظيفها وبناء طبقة تجهيز أولية

أي Dashboard جيد يبدأ ببيانات سليمة. لذلك لا تتجاوز خطوة التنظيف، لأن وجود تواريخ مكسورة أو درجات حرارة مفقودة سيؤدي إلى استنتاجات مضللة. ويمكن الرجوع أيضاً إلى تنظيف البيانات (Data Cleaning): اكتشاف ومعالجة القيم المفقودة (Missing Values) ومعالجة البيانات المكررة والمشوهة (Duplicates & Outliers) باستخدام بايثون.

import pandas as pd
import numpy as np

df = pd.read_csv("weather_data.csv")

df["date"] = pd.to_datetime(df["date"], errors="coerce")
df["city"] = df["city"].astype(str).str.strip()
df["weather_condition"] = df["weather_condition"].astype(str).str.strip()

numeric_cols = ["temperature", "humidity", "wind_speed"]
for col in numeric_cols:
    df[col] = pd.to_numeric(df[col], errors="coerce")

df = df.dropna(subset=["date", "city", "temperature"])
df = df.drop_duplicates()

df = df[(df["temperature"] > -30) & (df["temperature"] < 60)]
df = df[(df["humidity"] >= 0) & (df["humidity"] <= 100)]
df = df[(df["wind_speed"] >= 0)]

df["day_name"] = df["date"].dt.day_name()
df["month"] = df["date"].dt.to_period("M").astype(str)

print(df.head())
print(df.info())

في هذا الجزء قمنا ببناء طبقة تحضيرية صغيرة تشبه بيئة staging المصغرة. الفكرة هنا أن الملفات الخام نادراً ما تكون جاهزة للعرض المباشر، ولهذا نضيف تحويلات أولية تمنحنا حقولاً مشتقة مثل اسم اليوم والشهر لتسهيل التحليل الزمني.

في المشاريع الأكبر، من الأفضل فصل البيانات إلى ثلاث طبقات: raw للملفات الأصلية، وclean بعد المعالجة، وanalytics المخصصة للتقارير. هذه المعمارية تقلل الأخطاء وتسهّل إعادة التشغيل والتدقيق.

اشتقاق مؤشرات رئيسية لواجهة اللوحة

اللوحة لا تعرض كل شيء دفعة واحدة، بل تركز على مؤشرات مختصرة ثم تدعمها برسوم تفصيلية. لذلك سنحسب أولاً مجموعة KPIs بسيطة لكن مفيدة.

avg_temp = round(df["temperature"].mean(), 2)
max_temp = df["temperature"].max()
min_temp = df["temperature"].min()
avg_humidity = round(df["humidity"].mean(), 2)
top_condition = df["weather_condition"].mode()[0]

daily_summary = (
    df.groupby("date", as_index=False)
      .agg({
          "temperature": "mean",
          "humidity": "mean",
          "wind_speed": "mean"
      })
)

city_summary = (
    df.groupby("city", as_index=False)
      .agg({
          "temperature": "mean",
          "humidity": "mean",
          "wind_speed": "mean"
      })
      .sort_values(by="temperature", ascending=False)
)

print(avg_temp, max_temp, min_temp, avg_humidity, top_condition)

يعتمد هذا الجزء على مفاهيم التجميع والتلخيص التي ناقشناها بعمق في التجميع والتلخيص (Groupby & Aggregation): إنشاء تقارير إحصائية برمجية. الفكرة الأساسية أن اللوحة يجب أن تنقل القيم العامة بسرعة، ثم تسمح بمزيد من التفاصيل على مستوى التاريخ أو المدينة.

تصميم الرسوم المناسبة لبيانات الطقس

في لوحات الطقس، توجد ثلاثة أنواع من الرسوم تؤدي الغرض بكفاءة:

  1. مخطط خطي لتغير الحرارة عبر الزمن.
  2. مخطط عمودي لمقارنة متوسط الحرارة بين المدن.
  3. مخطط دائري أو شريطي لانتشار حالات الطقس مثل مشمس أو غائم أو ممطر.

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

import plotly.express as px

fig_temp = px.line(
    daily_summary,
    x="date",
    y="temperature",
    title="Average Daily Temperature",
    markers=True
)

fig_city = px.bar(
    city_summary,
    x="city",
    y="temperature",
    title="Average Temperature by City",
    color="temperature"
)

condition_counts = df["weather_condition"].value_counts().reset_index()
condition_counts.columns = ["weather_condition", "count"]

fig_condition = px.pie(
    condition_counts,
    names="weather_condition",
    values="count",
    title="Weather Condition Distribution"
)

fig_temp.show()
fig_city.show()
fig_condition.show()

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

بناء لوحة معلومات بسيطة باستخدام Streamlit

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

import streamlit as st
import pandas as pd
import plotly.express as px

st.set_page_config(page_title="Weather Dashboard", layout="wide")

df = pd.read_csv("weather_data.csv")
df["date"] = pd.to_datetime(df["date"], errors="coerce")
df = df.dropna(subset=["date", "city", "temperature"])

selected_city = st.sidebar.selectbox("Select City", sorted(df["city"].unique()))
filtered_df = df[df["city"] == selected_city].copy()

daily_city = (
    filtered_df.groupby("date", as_index=False)
    .agg({
        "temperature": "mean",
        "humidity": "mean",
        "wind_speed": "mean"
    })
)

st.title("Simple Weather Dashboard")
st.subheader(f"City: {selected_city}")

col1, col2, col3 = st.columns(3)
col1.metric("Avg Temp", round(filtered_df["temperature"].mean(), 2))
col2.metric("Avg Humidity", round(filtered_df["humidity"].mean(), 2))
col3.metric("Max Wind Speed", round(filtered_df["wind_speed"].max(), 2))

fig_line = px.line(daily_city, x="date", y="temperature", title="Temperature Trend")
fig_bar = px.bar(daily_city, x="date", y="humidity", title="Humidity by Day")

st.plotly_chart(fig_line, use_container_width=True)
st.plotly_chart(fig_bar, use_container_width=True)

بهذا السكربت أصبحت لديك لوحة قابلة للتشغيل محلياً، ويمكن توسيعها لاحقاً لتشمل فلاتر زمنية، مقارنة مدينتين، أو حتى الربط مع API مباشر لبيانات الطقس.

دور التحليل الزمني وتحسين القراءة التنفيذية

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

كذلك يمكن استخدام مفاهيم الفلترة المتقدمة (Filtering & Sorting): استخراج رؤى دقيقة من ملايين السجلات لتحديد الأيام التي تجاوزت فيها الحرارة حداً معيناً أو الأيام ذات الرطوبة القصوى، وهي وظائف بسيطة ظاهرياً لكنها مفيدة جداً في لوحات التشغيل اليومية.

إذا ارتفع حجم البيانات من آلاف السجلات إلى ملايين القراءات القادمة من حساسات أو محطات متعددة، ففكّر بنقل المعالجة من Pandas إلى PySpark. هذا الانتقال يمنحك قابلية توسع أعلى، خاصة عند تنفيذ عمليات تجميع زمنية كبيرة أو دمج مصادر طقس متعددة.

أفضل الممارسات لنجاح المشروع وتطويره لاحقاً

لجعل المشروع أكثر احترافية، اتبع الخطوات التالية:

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

هذا النوع من المشاريع المصغرة يترجم عملياً ما تعلّمته في مدخل إلى علوم البيانات: كيف تحول الأرقام العشوائية إلى قرارات استراتيجية؟، لأنه يحول قيماً مبعثرة داخل ملف إلى مؤشرات وقراءات تنفيذية يمكن فهمها واتخاذ قرارات بناءً عليها.

الخاتمة

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

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

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *