1 - مقدّمه و نصب Matplotlib

بصری‌سازی داده‌ها به کاویدن داده‌ها از طریق نمایش بصری می‌پردازد. این مقوله رابطه‌ی نزدیکی با تحلیل داده‌ها دارد که از برنامه‌ها برای یافتن الگوها و ارتباط‌ها در یک مجموعه از داده‌ها بهره می‌گیرد. مجموعه‌ی داده‌ها می‌تواند لیست کوچکی از اعداد باشد که در یک خطّ کد جا می‌شود یا چند گیگابایت داده را دربربگیرد.

ساختن نمایش‌های زیبا از داده‌ها چیزی بیشتر از ایجاد تصویرهای زیباست. زمانی که بیان و نمایش یک مجموعه‌ی داده ساده و از لحاظ بصری جذّاب باشد، معنای آن برای بینندگان شفّاف می‌شود. افراد الگوها و ویژگی‌هایی در داده‌های شما خواهند دید که هرگز از وجود آن‌ها خبر نداشته‌اند.

خوشبختانه برای بصری کردن داده‌های پیچیده نیازی به ابررایانه ندارید. به لطف بازدهی پایتون شما می‌توانید مجموعه‌های داده‌ای شامل میلیون‌ها داده‌ی مجزّا را تنها با یک لپ‌تاپ بکاوید. علاوه بر این لازم نیست حتماً نقاط داده عدد باشند. با مقدّماتی که در بخش اول این کتاب آموخته‌اید می‌توانید داده‌های غیر عددی را نیز تحلیل کنید.

مردم از پایتون برای کارهایی با فشردگیِ بالای داده استفاده می‌کنند، مانند ژنتیک، پژوهش‌های اقلیمی، تحلیل‌های سیاسی و اقتصادی و بسیاری دیگر. دانشمندان علوم داده مجموعه‌ی چشمگیری از ابزارها را برای بصری‌سازی و تحلیل در پایتون نوشته‌اند که بسیاری از آن‌ها در دسترس شما نیز هستند. یکی از محبوب‌ترین ابزارها کتابخانه‌ای برای کشیدن نمودارهای ریاضی به نام Matplotlib است. از این کتابخانه برای ساختن نمودارهای ساده مانند نمودار خطّی و پراکندگی استفاده می‌کنیم. سپس مجموعه‌ی داده‌ی جالب‌تری بر پایه‌ی مفهوم گردش تصادفی خواهیم ساخت— بصری‌سازی‌ای تولیدشده بر اساس مجموعه‌ای از تصمیم‌های تصادفی.

از بسته‌ای به نام Plotly نیز استفاده خواهیم کرد که بصری‌سازی‌های آن در دستگاه‌های دیجیتال بهتر دیده می‌شوند. پلات‌لی خروجی‌های بصری را به طور خودکار اندازه می‌کند تا در نمایشگرهای مختلف جا بگیرند. این خروجی‌ها شامل تعدادی ویژگی تعاملی هم هستند مانند تاکید بر جنبه‌های خاصّی از مجموعه‌ی داده وقتی کاربران روی بخش‌های مختلف نمودار می‌ایستند. از پلات‌لی برای تحلیل نتیجه‌های تاس انداختن استفاده خواهیم کرد.

روش نصب Matplotlib

برای استفاده از Matplotlib در اوّلین مجموعه از بصری‌سازی‌های خود باید آن را به کمک pip نصب کنید. pip ماژولی برای دریافت و نصب بسته‌های پایتون است. فرمان زیر را در یک اعلان ترمینال وارد کنید:

1
$ python -m pip install --user matplotlib

این فرمان از پایتون می‌خواهد تا ماژول pip را اجرا کرده و بسته‌ی matplotlib را به مجموعه‌ی پایتون نصب‌شده برای کاربر فعلی اضافه کند. اگر شما در سیستم خود از فرمان دیگری به جز python، مانند python3، برای اجرای برنامه‌ها یا آغاز یک نشست ترمینال استفاده می‌کنید، دستور شما به شکل زیر خواهد بود:

1
$ python3 -m pip install --user matplotlib
نکته
این فرمان در macOS کار نمی‌کند، به جای آن همین فرمان را بدون پرچم –user امتحان کنید.

برای بررسی انواع بصری‌سازی قابل ایجاد با Matplotlib سری به گالری نمونه‌های آن در https://matplotlib.org/gallery/ بزنید. اگر روی هر کدام از بصری‌سازی‌های موجود در گالری کلیک کنید کدی که آن را ایجاد کرده خواهید دید.

2 - رسم یک نمودار خطّی ساده

بیایید به کمک Matplotlib یک نمودار خطّی ساده رسم کنیم و سپس آن را برای ساختن یک بصری‌سازی داده‌ی گویاتر شخصی‌سازی کنیم. از یک دنباله‌ی اعداد مربّع ۱، ۴، ۹، ۱۶ و ۲۵ به عنوان داده‌ی این نمودار استفاده می‌کنیم.

کافی است اعداد را به Matplotlib بدهید، چنان‌که اینجا می‌بینید و Matplotlib باقی کارها را برای شما خواهد کرد:

1
2
3
4
5
6
7
8
9
import matplotlib.pyplot as plt

squares = [1, 4, 9, 16, 25]

fig, ax = plt.subplots()

ax.plot(squares)

plt.show()

ابتدا ماژول pyplot را با نام مستعار plt وارد می‌کنیم تا مجبور نباشیم هر دفعه pyplot را بنویسیم. (این نامگذاری را به صورت یک قرارداد در مثال‌های آنلاین خواهید دید بنابراین ما هم از همین استفاده می‌کنیم.) ماژول پای‌پلات شامل تعدادی تابع برای تولید نمودار است.

لیستی به نام squares می‌سازیم تا داده‌ها را برای رسم ذخیره کند. سپس با فراخوانی تابع subplots در ۱ از یکی دیگر از قراردادهای Matplotlib پیروی می‌کنیم. این تابع یکی تا چند نمودار را در یک شکل واحد رسم می‌کند. متغیّر fig بیانگر شکل کلّی یا همان مجموعه‌ی نمودارهایی است که تولید می‌شوند. متغیّر ax یکی از نمودارهای داخل شکل را نشان می‌دهد و متغیّری است که بیشتر اوقات از آن استفاده می‌کنیم.

سپس از متد plot() بهره می‌گیریم که تلاش می‌کند داده‌ی ورودی را به روشی معنادار رسم کند. تابع plt.show() نمایشگر Matplotlib را باز می‌کند و نمودار را نشان می‌دهد. نمایشگر به شما امکان بزرگنمایی و پیمایش نمودار را می‌دهد و اگر روی آیکون ذخیره کلید کنید می‌توانید هر نموداری را که خواستید ذخیره کنید.

3 - تغییر دادن نوشته‌ی برچسب و ضخامت خط

هرچند نمودار قبلی افزایشی بودن اعداد را نشان می‌دهد امّا نوشته‌ی روی محورها کوچک و خط رسم‌شده کمی نازک است که باعث خوانایی پایین می‌شود. خوشبختانه Matplotlib به شما امکان می‌دهد که تمام ویژگی‌های یک بصری‌سازی را تغییر دهید.

ما تعداد کمی از تغییرات ممکن را اعمال می‌کنیم تا خوانایی نمودار را افزایش دهیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt

squares = [1, 4, 9, 16, 25]

fig, ax = plt.subplots()

ax.plot(squares, linewidth=3)

# Set chart title and label axes.

ax.set_title("Square Numbers", fontsize=24)

ax.set_xlabel("Value", fontsize=14)

ax.set_ylabel("Square of Value", fontsize=14)

# Set size of tick labels.

ax.tick_params(axis='both', labelsize=14)

plt.show()

پارامتر linewidth در ۱ ضخامت خطی را تنظیم می‌کند که plot() تولید می‌کند. متد set_title() در ۲ عنوانی برای نمودار تعیین می‌کند. پارامترهای fontsize که چند بار در کد تکرار شده‌اند اندازه‌ی متن را در اجزای مختلف نمودار تغییر می‌دهد.

متدهای set_xlabel() و set_ylabel() به شما امکان می‌دهند که برای هر محور عنوانی تعیین کنید (۳) و متد tick_params() نشانه‌گذاری‌های روی محور را شکل می‌دهد (۴). نشان‌وندهایی که اینجا آمده بر روی هر دو محور تأثیر می‌گذارد(axis=‘both’) و اندازه‌ی برچسب این نشانه‌گذاری‌ها را ۱۴ قرار می‌دهد (labelsize=14).

خواندن نمودار حاصل بسیار راحت‌تر شده است. نوشته‌ی برچسب‌ها بزرگتر و خط نمودار ضخیم‌تر شده است. اغلب می‌ارزد که با این مقدارها بازی کنید تا به ایده‌ای کلّی درباره‌ی بهتر به نظر رسیدن نمودار نهایی برسید.

4 - اصلاح نمودار

حال که می‌توانیم نمودار را بهتر بخوانیم می‌بینیم که داده به درستی رسم نشده است. به انتهای نمودار توجّه کنید که مربّع 4.0، 25 نشان داده شده است! بیایید این مشکل را رفع کنیم.

زمانی که به plot() دنباله‌ای از اعداد می‌دهیم، فرض می‌کند که اوّلین داده متناظر با مقدار 0 در محور x است امّا اوّلین داده‌ی ما مربوط به مقدار ۱ در این محور است. می‌توانیم این رفتار پیش‌فرض را با دادن مقدارهای ورودی و خروجی به‌کاررفته برای محاسبه‌ی مربّعات به این متد تغییر دهیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import matplotlib.pyplot as plt

input_values = [1, 2, 3, 4, 5]

squares = [1, 4, 9, 16, 25]

fig, ax = plt.subplots()

ax.plot(input_values, squares, linewidth=3)

# Set chart title and label axes.

--snip--

اکنون plot() داده‌ها را درست رسم می‌کند زیرا مقدارهای ورودی و خروجی را به آن داده‌ایم و دیگر در مورد روش تولید خروجی‌ها فرضی نمی‌کند. نمودار حاصل درست است.

هنگام استفاده از plot() می‌توانید نشان‌وندهای متعدّدی را تعیین کنید و از تعداد زیادی تابع برای شخصی‌سازی نمودارهای خود بهره بگیرید. این تابع‌های شخصی‌سازی را هنگام کار کردن با مجموعه‌داده‌های جذّاب‌تر در طول فصل بیشتر بررسی خواهیم کرد.

5 - به‌کارگیری شیوه‌های پیش‌ساخته

Matplotlib تعداد شکل و شیوه‌ی ازپیش‌تعریف‌شده در اختیار می‌گذارد که تنظیمات اوّلیّه‌ی خوبی برای رنگ پس‌زمینه، خطوط شبکه‌بندی، ضخامت خط‌ها، فونت‌ها، اندازه‌ی فونت‌ها و بسیاری دیگر از ویژگی‌ها دارد که بصری‌سازی‌های شما را بدون نیاز به شخصی‌سازی خاصّی جذّاب جلوه می‌دهد. برای دیدن این شکل و شیوه‌ها در سیستم خود خط‌های زیر را در یک نشست ترمینال اجرا کنید:

1
2
3
4
>>> import matplotlib.pyplot as plt
>>> plt.style.available
['seaborn-dark', 'seaborn-darkgrid', 'seaborn-ticks', 'fivethirtyeight',
--snip--

برای به‌کارگیری هرکدام از این‌ها یک خط کد را پیش از آغاز ایجاد نمودار اضافه کنید:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import matplotlib.pyplot as plt

input_values = [1, 2, 3, 4, 5]

squares = [1, 4, 9, 16, 25]

plt.style.use('seaborn')

fig, ax = plt.subplots()

--snip--

این کد نموداری می‌کشد که از شیوه‌ی شکل‌دهی پیش‌ساخته‌ی seaborn استفاده می‌کند. گستره‌ی بزرگی از این شیوه‌های شکل‌دهی وجود دارد؛ با آن‌ها سر و کله بزنید تا چیزی مناسب سلیقه‌ی خود پیدا کنید.

6 - رسم و شکل‌دهی نقاط با scatter()

گاهی رسم و شکل دادن نقطه‌های مجزّا که مبنای آن‌ها خصوصیّات مشترکی است، سودمند است. برای مثال شاید بخواهید مقدارهای کوچک را با یک رنگ و مقدارهای بزرگ را با رنگی دیگر رسم کنید. همچنین می‌توانید مجموعه‌ی بزرگی از داده‌ها را به شکل و شیوه‌ی خاصّی رسم کنید و سپس برای تاکید بیشتر برای نقطه‌های مجزّا و خاصّی، این نقطه‌ها را مجدّداً با تنظیمات دیگری رسم کنید.

برای رسم یک نقطه از متد scatter() استفاده کنید. مقدارهای (x, y) نقطه‌ی مورد نظر خود را به این متد بدهید تا آن‌ را رسم کند:

1
2
3
4
5
6
7
8
9
import matplotlib.pyplot as plt

plt.style.use('seaborn')

fig, ax = plt.subplots()

ax.scatter(2, 4)

plt.show()

بیایید شکل و سیاق خروجی را تغییر دهیم تا جالب‌تر به نظر بیاید. یک عنوان و برچسب محورها را اضافه می‌کنیم و اطمینان حاصل می‌کنیم که نوشته‌ها به اندازه‌ی کافی بزرگ هستند تا راحت خوانده شوند:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt

plt.style.use('seaborn')

fig, ax = plt.subplots()

ax.scatter(2, 4, s=200)

# Set chart title and label axes.

ax.set_title("Square Numbers", fontsize=24)

ax.set_xlabel("Value", fontsize=14)

ax.set_ylabel("Square of Value", fontsize=14)

# Set size of tick labels.

ax.tick_params(axis='both', which='major', labelsize=14)

plt.show()

در ۱ scatter() را فرامی‌خوانیم و از نشان‌وند s برای تنظیم اندازه‌ی نقطه‌های به‌کاررفته برای رسم نمودار استفاده می‌کنیم. اگر اکنون scatter_squares.py را اجرا کنید باید نقطه‌ای تنها در وسط نمودار ببینید.

رسم مجموعه‌ای از نقاط با scatter()

برای رسم مجموعه‌ای از نقطه‌ها می‌توانیم لیستی جداگانه از مقدارهای x و y به آن بدهیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import matplotlib.pyplot as plt

x_values = [1, 2, 3, 4, 5]

y_values = [1, 4, 9, 16, 25]

plt.style.use('seaborn')

fig, ax = plt.subplots()

ax.scatter(x_values, y_values, s=100)

# Set chart title and label axes.

--snip--

لیست x_values شامل اعدادی است که باید مربّع شوند و y_values شامل مربّع هر عدد است. زمانی که این دو لیست را به scatter() می‌دهید، Matplotlib هنگام رسم هر نقطه از هر کدام یک مقدار را می‌خواند. نقطه‌هایی که باید رسم شوند (1,1)، (2,4)، (3,9)، (4, 16) و (5, 25) است.

محاسبه‌ی خودکار داده‌ها

نوشتن دستی لیست‌ها کارآمد نیست به ویژه زمانی که با داده‌های بسیار زیادی سر و کار داریم. به جای انتقال نقطه‌ها به شکل لیست، از یک حلقه استفاده می‌کنیم تا پایتون محاسبات را برای ما انجام دهد.

اینجا این روش را با وجود ۱۰۰۰ نقطه می‌بینیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import matplotlib.pyplot as plt

x_values = range(1, 1001)

y_values = [x**2 for x in x_values]

plt.style.use('seaborn')

fig, ax = plt.subplots()

ax.scatter(x_values, y_values, s=10)

# Set chart title and label axes.

--snip--

# Set the range for each axis.

ax.axis([0, 1100, 0, 1100000])

plt.show()

از گستره‌ی مقدارهای x شامل اعداد ۱ تا ۱۰۰۰ شروع می‌کنیم (۱). سپس به کمک روش دربرداری (for x in x_values) در مقدارهای x حلقه می‌زنیم، هر کدام را به توان ۲ می‌رسانیم (x**2) و نتیجه‌ها را در y_values ذخیره می‌کنیم. سپس لیست‌های ورودی و خروجی را به scatter() می‌دهیم (۲). چون تعداد داده‌ها در این مجموعه زیاد است اندازه‌ی نقطه‌ها را کوچک‌تر می‌کنیم.

در ۳ از متد axis() برای تعیین گستره‌ی هر محور استفاده می‌کنیم. این متد ۴ مقدار می‌پذیرد: کمینه و بیشینه‌ی مقدارهای محور x و y. اینجا محور x را بین ۰ و ۱۱۰۰ و محور y را بین ۰ و ۱،۱۰۰،۰۰۰ قرار می‌دهیم.

7 - رنگ‌آمیزی و ذخیره‌سازی نمودارها

تعریف کردن رنگ‌های دلخواه

برای تغییر رنگ نقطه‌ها c را به همران نام رنگ در علامت نقل قول به scatter() بدهید، مانند زیر:

1
ax.scatter(x_values, y_values, c='red', s=10)

علاوه بر این می‌توانید رنگ‌های دلخواه را به کمک مدل رنگی RGB هم تعیین کنید. برای این کار نشان‌وند c را به همراه یک چندتایی شامل سه مقدار اعشاری بین ۰ و ۱ (به ترتیب برای رنگ قرمز، سبز و آبی) وارد کنید. برای مثال خطّ زیر نموداری با نقطه‌های سبز کم‌رنگ ایجاد می‌کند:

1
ax.scatter(x_values, y_values, c=(0, 0.8, 0), s=10)

مقدارهای نزدیک‌تر به ۰ رنگ‌های تیره و مقدارهای نزدیک‌تر به ۱ رنگ‌های روشن‌تر تولید می‌کنند.

استفاده از نقشه‌ی رنگی

نقشه‌ی رنگی دنباله‌ای از رنگ‌های محوشونده است که از یک رنگ آغاز به رنگی ختم می‌شوند. کاربرد نقشه‌های رنگی در بصری‌سازی پررنگ کردن الگویی در داده‌هاست. برای مثال می‌توانید مقدارهای کم را با رنگ روشن و مقادیر زیاد را با رنگی تیره نمایش دهید.

ماژول pyplot مجموعه‌ای از نقشه‌های رنگی پیش‌ساخته دارد. برای استفاده کردن از آن‌ها باید مشخّص کنید که pyplot چگونه به هر نقطه‌ی مجموعه‌داده رنگی اختصاص دهد. اینجا روش اختصاص رنگ را بر اساس مقدار y نقطه می‌بینیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import matplotlib.pyplot as plt

x_values = range(1, 1001)

y_values = [x**2 for x in x_values]

ax.scatter(x_values, y_values, c=y_values, cmap=plt.cm.Blues, s=10)

# Set chart title and label axes.

--snip--

لیستی از مقدارهای y را به c نسبت می‌دهیم و سپس با نشان‌وند cmap به pyplot می‌گوییم که از کدام نقشه‌ی رنگی استفاده کند. این کد نقاطی را که مقدار y آن‌ها کمتر است با آبی روشن و آن‌هایی را که مقدار y بیشتری دارند با آبی تیره رنگ‌آمیزی می‌کند.

نکته
می‌توانید تمام نقشه‌های رنگی موجود در pyplot را در آدرس https://matplotlib.org ببینید؛ به قسمت Examples بروید، پایین بروید تا به Colors برسید و روی Colormap reference کلیک کنید.

ذخیره‌سازی خودکار نمودارها

اگر بخواهید که برنامه‌تان نمودار را به طور خودکار در فایلی ذخیره کند، می‌توانید فراخوانی plt.show() را با plt.savefig() جایگزین کنید:

1
plt.savefig('squares_plot.png', bbox_inches='tight')

نشانوند نخست نام فایلی است که برای تصویر نمودار انتخاب می‌کنید. این فایل در همان پوشه‌ی scatter_squares.py ذخیره خواهد شد. نشانوند دوم فاصله‌های خالی اضافی اطراف نمودار را حذف می‌کند. اگر می‌خواهید این فضای خالی باقی بماند کافی‌است این نشاوند را حذف کنید.

خودآزمایی

۱۵-۱- عددهای مکعب‌: توان سوم هر عدد را مکعّب آن می‌خوانند. ابتدا نمودار ۵ عدد مکعّب نخست را بکشید سپس این کار را برای ۵۰۰۰ عدد مکعّب نخست تکرار کنید.

۱۵-۲- اعداد مکعّب رنگی: یک نقشه‌ی رنگی روی نمودار اعداد مکعّب اعمال کنید.

8 - گردش تصادفی

در این بخش از پایتون برای تولید داده برای گردش تصادفی استفاده می‌کنیم و سپس به کمک Matplotlib نمایش بصری جذّابی از این داده‌ها می‌سازیم. گردش تصادفی مسیری است که هیچ جهت مشخّصی ندارد امّا بر اساس دنباله‌ای از تصمیم‌های تصادفی تعیین می‌شود که هر کدام از تصمیم‌ها کاملاً تصادفی گرفته می‌شوند. شما می‌توانید گردش تصادفی را مانند حرکت مورچه‌ای سرگردان در نظر بگیرید که هر قدم خود را در جهتی تصادفی برمی‌دارد.

گردش‌های تصادفی کاربردهایی عملی در علوم طبیعی، فیزیک، زیست‌شناسی، شیمی و اقتصاد دارد. برای مثال دانه‌ی گرده‌ای که در قطره‌ای آب شناور است به این دلیل روی سطح آب حرکت می‌کند که مولکول‌های آب آن به طور مداوم به اطراف هل می‌دهند. حرکت مولکولی در یک قطره‌ی آب تصادفی است بنابراین مسیری که دانه‌ی گرده روی سطح طی می‌کند گردشی تصادفی به حساب می‌آید. کدی که در ادامه می‌نویسیم بسیاری از وضعیّت‌های جهان واقعی را مدل می‌کند.

ساختن کلاس RandomWalk()

برای ایجاد یک گردش تصادفی کلاس RandomWalk را ایجاد می‌کنیم که در مورد جهت حرکتی که باید انجام بگیرد تصمیم‌های تصادفی می‌گیرد. کلاس سه مشخّصه نیاز دارد: یک متغیّر برای ذخیره کردن تعداد نقطه‌ها در گردش و دو لیست برای ذخیره کردن مقدار مختصّات x و y هر نقطه‌ی حرکت.

تنها دو متد در کلاس RandomWalk مورد نیاز است: __init__() و fill_walk() که نقطه‌های حرکت را محاسبه می‌کند. از متد __init__() شروع می‌کنیم:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from random import choice

class RandomWalk:
    """A class to generate random walks."""

    def __init__(self, num_points=5000):
        """Initialize attributes of a walk."""
        self.num_points = num_points

        # All walks start at (0, 0).
        self.x_values = [0]
        self.y_values = [0]

برای گرفتن تصمیم‌های تصادفی حرکت‌های ممکن را در لیستی ذخیره می‌کنیم و سپس از تابع choice() از ماژول random استفاده می‌کنیم تا تصمیم بگیریم که در هر گام کدام حرکت را انجام دهیم (۱). سپس تعداد پیش‌فرض نقطه‌ها را در یک گردش ۵۰۰۰ قرار می‌دهیم که برای تولید چند الگوی جالب کافی است و در عین حال برای تولید سریع گردش‌ها به اندازه‌ی کافی کوچک است (۲). سپس در ۳ دو لیست برای مقدارهای x و y می‌سازیم و شروع هر گردش را نقطه‌ی (0, 0) قرار می‌دهیم.

9 - انتخاب جهت و رسم گردش تصادفی

انتخاب جهت

مانند آن‌چه در ادامه می‌آید، از متد fill_walk() برای پر کردن مسیر گردش خود از نقطه‌ها استفاده و در هر گام جهت حرکت را تعیین می‌کنیم. این متد را به random_walk.py اضافه کنید:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def fill_walk(self):
    """Calculate all the points in the walk."""

    # Keep taking steps until the walk reaches the desired length.
    while len(self.x_values) < self.num_points:

        # Decide which direction to go and how far to go in that direction.
        x_direction = choice([1, -1])
        x_distance = choice([0, 1, 2, 3, 4])
        x_step = x_direction * x_distance

        y_direction = choice([1, -1])
        y_distance = choice([0, 1, 2, 3, 4])
        y_step = y_direction * y_distance

        # Reject moves that go nowhere.
        if x_step == 0 and y_step == 0:
            continue

        # Calculate the new position.
        x = self.x_values[-1] + x_step
        y = self.y_values[-1] + y_step

        self.x_values.append(x)
        self.y_values.append(y)

در ۱ حلقه‌ای برپا می‌کنیم که اجرای آن تا پر شدن گردش با تعداد درستی نقطه ادامه می‌یابد. بخش اصلی متد fill_walk() از پایتون می‌خواهد که چهار تصمیم تصادفی را شبیه‌سازی کند: گردش به چپ می‌رود یا راست؟ در آن جهت چه‌قدر پیش می‌رود؟ آیا بالا می‌رود یا پایین؟ در این جهت چه‌قدر حرکت می‌کند؟

از choice([1, -1]) برای انتخاب مقدار x_direction استفاده می‌کنیم که یا ۱ (برای حرکت به راست) برمی‌گرداند یا ۱- (برای رفتن به چپ) (۲). سپس choice([0, 1, 2, 3, 4]) به پایتون می‌گوید که با انتخاب عددی صحیح بین ۰ و ۴، در آن جهت (x_direction) چه‌قدر حرکت کند. (آوردن ۰ در این لیست به ما امکان می‌دهد که در جهت محور y حرکت کنیم و در عین حال بتوانیم گام‌هایی در جهت هر دو محور داشته باشیم.)

در ۳ و ۴ طول هر گام در جهت‌های x و y را با ضرب کردنِ جهتِ هر حرکت در فاصله‌ای که انتخاب‌شده حساب می‌کنیم. حاصل مثبت برای x_step به معنای حرکت به راست، حاصل منفی به معنای حرکت به چپ و صفر به معنای حرکت عمودی است. مقداری مثبت برای y_step به معنای حرکت به بالا، مقدار منفی به معنای حرکت به پایین و ۰ به معنای حرکت افقی است. اگر هر دو مقدار x_step و y_step صفر شود به جایی نمی‌رویم در نتیجه با صرف نظر از این حرکت حلقه را ادامه می‌دهیم. (۵)

برای به دست آوردن مقدار بعدی x، مقدار x_step را به آخرین مقدار ذخیره‌شده‌ی x_values اضافه می‌کنیم (۶) و همین کار را برای مقدارهای y تکرار می‌کنیم. زمانی که این مقدارها محاسبه شدند آن‌ها را به x_values و y_values الحاق می‌کنیم.

رسم گردش تصادفی

کد زیر تمام نقطه‌های یک گردش را رسم می‌کند:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import matplotlib.pyplot as plt

from random_walk import RandomWalk

# Make a random walk.
rw = RandomWalk()

rw.fill_walk()

# Plot the points in the walk.
plt.style.use('classic')

fig, ax = plt.subplots()

ax.scatter(rw.x_values, rw.y_values, s=15)

plt.show()

کار را با وارد کردن pyplot و RandomWalk شروع می‌کنیم. سپس گردشی تصادفی می‌سازیم و آن را در rw ذخیره می‌کنیم (۱) و سپس از فراخوانی fill_walk() مطمئن می‌شویم. در ۲ مقادیر x و y گردش را به scatter() می‌دهیم و اندازه‌ی مناسبی برای نقطه‌ها انتخاب می‌کنیم.