Jannah Theme License is not validated, Go to the theme options page to validate the license, You need a single license for each domain name.
تقنية وتكنولوجيا

إنشاء لوحة تحكم أفضل – أسطورة أم حقيقة؟ – التقنية اليوم


تصوير لوكاس بلازيك على Unsplash

إنشاء لوحة تحكم أفضل – أسطورة أم حقيقة؟

تم إنشاء الإصدار التجريبي 2.0 الخاص بي باستخدام Dash & Plotly بدلاً من Matplotlib

مقدمة

في فبراير 2023 كتبت أول مشاركة لي على Medium:

كيفية تخصيص الرسوم البيانية في بايثون: النصائح والحيل

شرحت هنا كيفية إنشاء لوحة معلومات مبسطة تحتوي على مخططات متنوعة، بما في ذلك مخطط خطي ومخططات دائرية وشريطية وخريطة تصحيحية. للتآمر عليهم استخدمت Matplotlib “القديم الجيد”. [1]لأنني كنت على دراية بكلماته الرئيسية ووظائفه الرئيسية. ما زلت أعتقد أن Matplotlib هي مكتبة رائعة لبدء رحلة البيانات الخاصة بك مع Python، حيث توجد قاعدة معرفية جماعية كبيرة جدًا. إذا كان هناك شيء غير واضح مع Matplotlib، فيمكنك البحث في Google عن استفساراتك وعلى الأرجح ستحصل على إجابات.

ومع ذلك، قد يواجه Matplotlib بعض الصعوبات عند إنشاء تصورات تفاعلية ومستندة إلى الويب. للغرض الأخير، بلوتلي [2] يمكن أن يكون بديلاً جيدًا، مما يسمح لك بإنشاء لوحات معلومات تفاعلية غير عادية. من ناحية أخرى، تعد Matplotlib مكتبة قوية توفر تحكمًا أفضل في تخصيص قطعة الأرض، وهو أمر جيد لإنشاء تصورات جاهزة للنشر.

في هذه التدوينة سأحاول الاستبدال الكود الذي يستخدم Matlab (١) مع هذا يعتمد على بلوتلي (2). سوف يكرر الهيكل المنشور الأولي، بسبب أنواع المؤامرات وبيانات الإدخال [3] هي نفسها. ولكنني سأضيف هنا بعض الملاحظات حول مستوى التشابه بين (1) و(2) لكل نوع من أنواع القطع. هدفي الرئيسي من كتابة هذا المقال هو الرجوع إلى مشاركتي الأولى ومحاولة إعادة صياغتها بمستوى معرفتي الحالي.

ملحوظة: سوف تتفاجأ بمدى قصر كود Plotly المطلوب لبناء خريطة التصحيح 🙂

لكن أول الأشياء أولاً، سنبدأ بإنشاء رسم بياني خطي في Plotly.

#1. مؤامرة خط

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

يمكنك العثور أدناه على مقتطف كود باستخدام Plotly الذي ينتج مخططًا خطيًا يوضح متوسط ​​الحضور في كأس العالم FIFA خلال الفترة 1990-2018: يتم تمييز كل قيمة بملصق ونقطة مبعثرة ملونة.

## Line Plot ##

import plotly.graph_objects as go

time = [1990, 1994, 1998, 2002, 2006, 2010, 2014, 2018]
numbers = [48411, 68626, 44676, 42571, 52609, 49499, 53772, 47371]
labels = ['Italy', 'USA', 'France', 'Japan / South Korea', 'Germany',
'South Africa', 'Brazil', 'Russia']

fig = go.Figure()

# Line plot
fig.add_trace(go.Scatter(x=time, y=numbers, mode='lines+markers',
marker=dict(color='black',size=10), line=dict(width=2.5)))

# Scatter plot
for i in range(len(time)):
fig.add_trace(go.Scatter(x=[time[i]], y=[numbers[i]],
mode='markers', name=labels[i]))

# Layout settings
fig.update_layout(title='Average number of attendees per game in 1990-2018',
xaxis=dict(tickvals=time),
yaxis=dict(range=[35000, 70000]),
showlegend=True,
legend=dict(x=0.5, y=-0.2),
plot_bgcolor='white')

fig.show()

والنتيجة تبدو كما يلي:

مؤامرة خطية مبنية باستخدام Plotly. الصورة من قبل المؤلف.

عند تحريك مؤشر الفأرة فوق أي نقطة من الرسم البياني في بلوتلي، تظهر نافذة توضح عدد المتفرجين واسم الدولة التي أقيمت فيها البطولة.

مستوى التشابه مع مؤامرة Matplotlib: 8 من أصل 10.
بشكل عام، يبدو الكود مشابهًا جدًا للمقتطف الأولي من حيث البنية وموضع كتل الكود الرئيسية بداخله.

ما هو الفرق: ومع ذلك، يتم عرض بعض الاختلافات أيضا. على سبيل المثال، انتبه إلى تفاصيل كيفية الإعلان عن عناصر الرسم (على سبيل المثال، وضع رسم خطي، خطوط + علامات تسمح بعرضها في وقت واحد).

ما هو مهم: لبناء هذه المؤامرة، أستخدم الوحدة Plotly.graph_objects (التي يتم استيرادها كما هو الحال). فهو يوفر تسلسلاً هرميًا يتم إنشاؤه تلقائيًا من الفئات التي تسمى “كائنات الرسم البياني” والتي يمكن استخدامها لتمثيل الأشكال المختلفة.

#2. مخطط دائري (في الواقع، مخطط دائري مجوف)

تعد المخططات الدائرية والدائرية جيدة جدًا لإظهار مساهمات القيم المختلفة في المبلغ الإجمالي: فهي مقسمة إلى شرائح، والتي توضح القيمة التناسبية لكل جزء من بياناتنا.

فيما يلي مقتطف التعليمات البرمجية في Plotly الذي يتم استخدامه لإنشاء مخطط دائري يعرض النسبة بين البلدان التي حصلت على أكبر عدد من ألقاب كأس العالم.

## Pie Chart ##

import plotly.express as px

# Data
label_list = ['Brazil', 'Germany', 'Italy', 'Argentina', 'Uruguay', 'France', 'England', 'Spain']
freq = [5, 4, 4, 3, 2, 2, 1, 1]

# Customize colors
colors = ['darkorchid', 'royalblue', 'lightsteelblue', 'silver', 'sandybrown', 'lightcoral', 'seagreen', 'salmon']

# Building chart
fig = px.pie(values=freq, names=label_list, title='Countries with the most FIFA World Cup titles',
color_discrete_map=dict(zip(label_list, colors)),
labels={'label': 'Country', 'value': 'Frequency'},
hole=0.3)

fig.update_traces(textposition='inside', textinfo='percent+label')
fig.show()

العنصر المرئي الناتج موضح أدناه (بالمناسبة، إنه مخطط تفاعلي أيضًا!):

مخطط دائري تم إنشاؤه باستخدام Plotly. الصورة من قبل المؤلف.

مستوى التشابه مع مؤامرة Matplotlib: 7 من أصل 10. مرة أخرى، منطق الكود هو نفسه تقريبًا بالنسبة للإصدارين.

ما هو الفرق: قد يلاحظ المرء أنه بمساعدة الكلمة الأساسية “hole” من الممكن تحويل المخطط الدائري إلى مخطط دائري مجوف. وشاهد مدى سهولة وبساطة عرض النسب المئوية لكل جزء من المخطط في Plotly مقارنةً بـ Matplotlib.

ما هو مهم: بدلاً من استخدام وحدةploly.graph_objects، أقوم هنا بتطبيق وحدةploly.express (عادةً ما يتم استيرادها بتنسيق px) التي تحتوي على وظائف يمكنها إنشاء أشكال كاملة مرة واحدة. هذه هي واجهة Plotly سهلة الاستخدام، والتي تعمل على مجموعة متنوعة من أنواع البيانات.

#3. شريط الرسم البياني

تعرض المخططات الشريطية، بغض النظر عما إذا كانت عمودية أو أفقية، مقارنات بين الفئات المختلفة. يُظهر المحور الرأسي (“الملعب”) للمخطط الفئات المحددة التي تتم مقارنتها، ويمثل المحور الأفقي قيمة مُقاسة، أي “السعة” بحد ذاتها.

## Bar Chart ##

import plotly.graph_objects as go

labels = ['Estádio do Maracanã', 'Camp Nou', 'Estadio Azteca',
'Wembley Stadium', 'Rose Bowl', 'Estadio Santiago Bernabéu',
'Estadio Centenario', 'Lusail Stadium']
capacity = [200, 121, 115, 99, 94, 90, 90, 89]

fig = go.Figure()

# Horizontal bar chart
fig.add_trace(go.Bar(y=labels, x=capacity, orientation='h', marker_color='blue'))

# Layout settings
fig.update_layout(title='Top-8 stadiums on capacity (in thousands)',
yaxis=dict(title='Stadiums'),
xaxis=dict(title='Capacity'),
showlegend=False,
plot_bgcolor='white')

fig.show()

مخطط شريطي أفقي تم إنشاؤه باستخدام Plotly. الصورة من قبل المؤلف.

مستوى التشابه مع مؤامرة Matplotlib: 6 من أصل 10.
بشكل عام، تحتوي قطعتا الكود على نفس الكتل تقريبًا، لكن الكود في Plotly أقصر.

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

ما هو مهم: لبناء هذا النوع من قطعة الأرض، تم استخدام وحدةploly.express أيضًا. بالنسبة للشريط الأفقي، يمكننا استخدام الدالة px.bar مع الاتجاه = ‘h’.

#4. خريطة تشوروبليث

تُعد خريطة Choropleth أداة رائعة لتصور كيفية اختلاف المتغير عبر منطقة جغرافية ما. تشبه الخريطة الحرارية، ولكنها تستخدم المناطق المرسومة وفقًا لنمط متغير بدلاً من المناطق الجغرافية كما تفعل الخرائط التصحيحية.

يمكنك أدناه رؤية رمز Plotly لرسم مخطط الكوريغرافيا. هنا تحصل كل دولة على لونها الخاص اعتمادًا على عدد المرات التي تعقد فيها كأس العالم لكرة القدم. استضافت الدول ذات اللون الأحمر الداكن البطولة مرتين، والدول ذات اللون الأحمر الفاتح – 1، وجميع الدول الأخرى (الرمادية) – 0.

## Choropleth Map ##

import polars as pl
import plotly.express as px

df = pl.read_csv('data_football.csv')
df.head(5)
fig = px.choropleth(df, locations='team_code', color='count',
hover_name='team_name', projection='natural earth',
title='Geography of the FIFA World Cups',
color_continuous_scale='Reds')
fig.show()

خريطة Choropleth مبنية باستخدام Plotly. الصورة من قبل المؤلف.

مستوى التشابه مع مؤامرة Matplotlib: 4 من أصل 10.
الكود الموجود في Plotly أصغر بثلاث مرات من الكود الموجود في Matplotlib.

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

  • لتنزيل مجلد مضغوط ne_110m_admin_0_countries.zip يحتوي على ملفات الأشكال لرسم الخريطة نفسها ورسم حدود الدولة وخطوط الشبكة وما إلى ذلك؛
  • لاستيراد عناصر Basemap وPolygon وPatchCollection من مكتبات mpl_toolkits.basemap وmatplotlib.patches وmatplotlib.collections واستخدامها لإنشاء خلفية ملونة بناءً على المنطق الذي اقترحناه في ملف data_football.csv.

ما هو مهم: وماذا يفعل بلوتلي؟ يستغرق الأمر نفس ملف data_football.csv وبمساعدة وظيفة px.choropleth يعرض البيانات المجمعة عبر مناطق أو بلدان مختلفة على الخريطة. يتم تلوين كل منها وفقًا لقيمة معلومات محددة معينة، في حالتنا هذا هو متغير العدد في ملف الإدخال.

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

تلخيص: إنشاء لوحة تحكم واحدة باستخدام Dash

يسمح Dash ببناء لوحة معلومات تفاعلية على أساس كود Python دون الحاجة إلى تعلم أطر عمل JavaScript المعقدة مثل React.js.

هنا يمكنك العثور على الكود والتعليقات على أجزائه المهمة:

import polars as pl
import plotly.express as px
import plotly.graph_objects as go
import dash
from dash import dcc
from dash import html

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

header = html.H2(children="FIFA World Cup Analysis")

## Line plot with scatters ##

# Data
time = [1990, 1994, 1998, 2002, 2006, 2010, 2014, 2018]
numbers = [48411, 68626, 44676, 42571, 52609, 49499, 53772, 47371]
labels = ['Italy', 'USA', 'France', 'Japan / South Korea', 'Germany', 'South Africa', 'Brazil', 'Russia']

# Building chart
chart1 = go.Figure()

chart1.add_trace(go.Scatter(x=time, y=numbers, mode='lines+markers',
marker=dict(color='black',size=10), line=dict(width=2.5)))

for i in range(len(time)):
chart1.add_trace(go.Scatter(x=[time[i]], y=[numbers[i]],
mode='markers', name=labels[i]))

# Layout settings
chart1.update_layout(title='Average number of attendees per game in 1990-2018',
xaxis=dict(tickvals=time),
yaxis=dict(range=[35000, 70000]),
showlegend=True,
plot_bgcolor='white')

plot1 = dcc.Graph(
id='plot1',
figure=chart1,
className="six columns"
)

## Pie chart ##

# Data
label_list = ['Brazil', 'Germany', 'Italy', 'Argentina', 'Uruguay', 'France', 'England', 'Spain']
freq = [5, 4, 4, 3, 2, 2, 1, 1]

# Customize colors
colors = ['darkorchid', 'royalblue', 'lightsteelblue', 'silver', 'sandybrown', 'lightcoral', 'seagreen', 'salmon']

# Building chart
chart2 = px.pie(values=freq, names=label_list, title='Countries with the most FIFA World Cup titles',
color_discrete_map=dict(zip(label_list, colors)),
labels={'label': 'Country', 'value': 'Frequency'},
hole=0.3)

chart2.update_traces(textposition='inside', textinfo='percent+label')

plot2 = dcc.Graph(
id='plot2',
figure=chart2,
className="six columns"
)

## Horizontal bar chart ##

labels = ['Estádio do Maracanã', 'Camp Nou', 'Estadio Azteca',
'Wembley Stadium', 'Rose Bowl', 'Estadio Santiago Bernabéu',
'Estadio Centenario', 'Lusail Stadium']
capacity = [200, 121, 115, 99, 94, 90, 90, 89]

# Building chart
chart3 = go.Figure()

chart3.add_trace(go.Bar(y=labels, x=capacity, orientation='h', marker_color='blue'))

# Layout settings
chart3.update_layout(title='Top-8 stadiums on capacity (in thousands)',
yaxis=dict(title='Stadiums'),
xaxis=dict(title='Capacity'),
showlegend=False,
plot_bgcolor='white')

plot3 = dcc.Graph(
id='plot3',
figure=chart3,
className="six columns"
)

## Chropleth map ##

# Data
df = pl.read_csv('data_football.csv')

# Building chart
chart4 = px.choropleth(df, locations='team_code', color='count',
hover_name='team_name', projection='natural earth',
title='Geography of the FIFA World Cups',
color_continuous_scale='Reds')

plot4 = dcc.Graph(
id='plot4',
figure=chart4,
className="six columns"
)

row1 = html.Div(children=[plot1, plot2],)
row2 = html.Div(children=[plot3, plot4])
layout = html.Div(children=[header, row1, row2], style={"text-align": "center"})

app.layout = layout

if __name__ == "__main__":
app.run_server(debug=False)

تعليقات على الكود:

  • أولاً، نحتاج إلى استيراد جميع المكتبات (بما في ذلك وحدات HTML) وتهيئة لوحة المعلومات بمساعدة السلسلة النصية app = Dash.Dash(__name__, External_stylesheets=external_stylesheets).
  • نقوم بعد ذلك بلصق كل رسم بياني في مكونات داش الأساسية لدمجها بشكل أكبر مع مكونات HTML الأخرى (dcc.Graph). هنا يحتاج className=”six columns” إلى استخدام نصف الشاشة لكل صف من قطع الأراضي.
  • بعد ذلك نقوم بإنشاء صفين من مكونات html.Div مع قطعتي أرض في كل منهما. بالإضافة إلى ذلك، يمكن استخدام ملف CSS بسيط مع سمة النمط لعرض رأس لوحة المعلومات الخاصة بنا في سلسلة التخطيط. تم تعيين هذا التخطيط كتخطيط التطبيق الذي تمت تهيئته من قبل.
  • وأخيرًا، تسمح الفقرة الأخيرة بتشغيل التطبيق محليًا (app.run_server(debug=False)). لرؤية لوحة التحكم، ما عليك سوى اتباع الرابط http://127.0.0.1:8050/ وستجد شيئًا مثل الصورة أدناه.
لوحة القيادة النهائية التي تم إنشاؤها باستخدام Dash. الصورة من قبل المؤلف.

الملاحظات الختامية

بصراحة السؤال في العنوان كان بلاغيًا، وأنت وحدك عزيزي القارئ من يستطيع أن يقرر ما إذا كان الإصدار الحالي من لوحة التحكم أفضل من السابق. لكن على الأقل بذلت قصارى جهدي (وأعتقد في أعماقي أن الإصدار 2.0 هو الأفضل) 🙂

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

آمل أن يشجعك هذا المنشور على إلقاء نظرة على مشاريعك النهائية ومحاولة إعادة تصميمها باستخدام التقنيات الجديدة المتاحة. هذا هو السبب الرئيسي الذي جعلني أقرر استبدال Matplotlib بـ Plotly & Dash (بالإضافة إلى أن الأخيرين يسهلان إنشاء نتائج تحليل البيانات).

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

و كالمعتاد، شكرا على القراءه!

مراجع

  1. الصفحة الرئيسية لمكتبة Matplotlib: https://matplotlib.org/stable/
  2. الصفحة الرئيسية لمكتبة Plotly: https://plotly.com/python/
  3. Fjelstul، Joshua C. “قاعدة بيانات كأس العالم Fjelstul v.1.0.” 8 يوليو 2022. https://www.github.com/jfjelstul/worldcup


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

رابط المصدر

اترك تعليقاً

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

زر الذهاب إلى الأعلى