ترسیم داده های جغرافیایی در پایتون — راهنمای جامع

۱۶۹۷ بازدید
آخرین به‌روزرسانی: ۱۷ تیر ۱۴۰۲
زمان مطالعه: ۱۱ دقیقه
ترسیم داده های جغرافیایی در پایتون — راهنمای جامع

یکی از مسائل مهم در کار «علم داده» (Data Science)، بصری‌سازی داده‌ها در یک نقشه جغرافیایی است و برای انجام این کار، «بسته‌های» (Packages) گوناگونی برای «زبان برنامه‌نویسی پایتون» (Python Programming Language) قابل استفاده هستند که از جمله آن‌ها می‌توان به «جئوپانداس» (GeoPandas) (+) اشاره کرد. اما گاهی نیز نصب این بسته‌ها، متناسب با محیطی که کاربر استفاده می‌کند ممکن است کار دشواری باشد. راهکار دیگر، استفاده از کدهایی است که توسط خود کاربر نوشته می‌شوند. در این مطلب «راه سخت» چگونگی ساخت «توابع نقشه‌های جغرافیایی» با استفاده از «Shapefiles» و کتابخانه‌های پایه‌ای پایتون آموزش داده خواهد شد. پس از مطالعه این راهنما کاربر قادر به ترسیم داده های جغرافیایی در پایتون است.

ترسیم داده‌های جغرافیایی با پایتون

۱. فایل‌های دارای فرمت Shapefiles

Shapefiles یک فرمت محبوب داده‌های بردار جغرافیایی برای نرم‌افزارهای «سیستم‌های اطلاعات جغرافیایی» (Geographic Information System | GIS است. این فرمت توسط «مؤسسه پژوهش سامانه‌های زیست‌محیطی | اِرزی» (Environmental Systems Research Institute | Esri) به عنوان یک «استاندارد باز» (Open Standard) برای قابلیت همکاری داده‌ای میان اِرزی و دیگر محصولات نرم‌افزاری سیستم‌های اطلاعات جغرافیایی تولید شده است.

فرمت فایل Shapefiles به طور فضایی هندسه را با «نقاط»، «چندخطی‌ها» یا «چندضلعی‌ها» توصیف می‌کند. در «OpenStreetMap» این موارد را می‌توان به ترتیب به عنوان «گره» (Node)، «راه‌ها» (ways) و «راه‌های بسته» (Closed Ways) در نظر گرفت. هر هندسه دارای مجموعه‌ای از خصیصه‌های مرتبط است. به طور کلی این موارد چیزی شبیه تگ‌های OSM (+) هستند. فایل shapefile در حقیقت یک گروه‌بندی از چندین فایل است که قالب‌بندی شده‌اند تا جنبه‌های گوناگون از داده‌های جغرافیایی را نمایش دهند. این موارد در ادامه بیان شده‌اند.

  • shp.: فرمت شکل؛ هندسه خود ویژگی
  • shx.: فرمت اندیس شکل؛ یک اندیس موقعیتی برای هندسه ویژگی به منظور پذیرش دنبال کردن رو به جلو و رو به عقب به طور سریع
  • dbf.: قالب خصیصه؛ خصیصه‌های ستونی برای هر شکل، در قالب dBase IV

چندین فایل اختیاری (قابل انتخاب) در فرمت shapefile وجود دارند. قابل توجه‌ترین این موارد فایل prj. است که سیستم مختصات و اطلاعات طرح‌ریزی را توصیف می‌کند. اگرچه فایل lyr. بخشی از استاندارد shapefile نیست، اما شامل آن می‌شود زیرا دارای مشخصه‌های چگونگی نمایش داده (رنگ، برچست و دیگر موارد) در نرم‌افزار «ArcGIS» (+) است.

۲. نصب کتابخانه پایتون Shapefile به نام PyShp

کتابخانه Shapefile پایتون به نام pyshp، از خواندن و نوشتن برای فرمت Shapefile اِرزی پشتیبانی می‌کند. فرمت Shapefile، یک فرمت داده برداری برای سیستم‌های اطلاعات جغرافیایی محبوب است که توسط اِرزی (+) تولید شده.

برای نصب pyshp، باید کد زیر را در ترمینال اجرا کرد.

1pip install pyshp

۳. ایمپورت کردن و مقداردهی اولیه کتابخانه‌های اصلی پایتون

1import numpy as np
2import pandas as pd
3import shapefile as shp
4import matplotlib.pyplot as plt
5import seaborn as sns

مقداردهی اولیه مجموعه بصری‌سازی

1sns.set(style=”whitegrid”, palette=”pastel”, color_codes=True)
2sns.mpl.rc(“figure”, figsize=(10,6))

کد زیر برای افرادی است که از «ژوپیتر نوت‌بوک» (Jupyter Notebook) استفاده می‌کنند.

1%matplotlib inline

۴. باز کردن یک نقشه برداری

همانطور که پیش‌تر بیان شد، یک نقشه بردار، گروهی از چندین نوع فایل است که shp. اصلی‌ترین آن‌ها محسوب می‌شود، و در واقع جایی است که ویژگی‌های جغرافیایی ذخیره شده‌اند. شایان توجه است که سایر فایل‌ها به صورت «name.dbf» ،«name.shx» و دیگر موارد باید در پوشه مشابهی باشند.

در این راهنما، با نقشه‌های مربوط به شهرها (Comunas) که در کنار هم «منطقه مادرشهری سانتیاگو» (Santiago Metropolitan Region) را می‌سازند کار می‌شود. در «موسسه آمار ملی شیلی» (Chilean National Institute of Statistics | INE) امکان دانلود گروهی از shapefile‌های مرتبط با نقشه‌ها که در آخرین سرشماری ملی سال ۲۰۱۷ ساخته شد وجود دارد.

  • Comuna.cpg
  • Comuna.shp
  • Comuna.dbf
  • Comuna.shp.xml
  • Comuna.prj
  • Comuna.shx
  • Comuna.sbn
  • Comuna.sbx
1shp_path =./Comunas_RM_Mapas_Vectoriales/Comuna.shp”
2sf = shp.Reader(shp_path)

اکنون می‌توان بررسی کرد که چه تعداد «شکل» (shape) متفاوت توسط تابع shp.Reader ایمپورت شده است.

1len(sf.shapes())

نتیجه برابر با ۵۲ است. این یعنی ۵۲ شکل روی فایل‌های shape وجود دارند و این به لحاظ مفهومی نیز صحیح است زیرا منطقه مادری (کلان‌شهری) دارای ۵۲ شهر (comunas) است که در نقشه زیر نمایش داده شده‌اند (پیش از پایان این مطلب، چگونگی ساخت نقشه‌ای مانند آنچه در شکل زیر مشاهده می‌شود، آموزش داده خواهد شد).

دیتافریم در Pandas

اکنون و با استفاده از کد زیر یکی از اشکال (یا رکوردها) جست‌و‌جو می‌شود.

1sf.records()[1]

نتیجه خروجی یک آرایه با ۶ عنصر است.

Out:
['13',
'131',
'13115',
'REGIÓN METROPOLITANA DE SANTIAGO',
'SANTIAGO',
'LO BARNECHEA']

عنصر [5] نام شهر (comuna) و برای این مورد «LO BARNECHEA» است. این شهر در بخش شرقی شهر قرار دارد که کوه‌های «Andes» واقع شده‌اند. می‌توان نام شهر را به طور مستقیم به صورت زیر دریافت کرد.

1Andes

مرکزی‌ترین بخش شهر «منطقه مادری سانتیاگو»، دقیقا «Comuna of Santiago» است که «کلیسای جامع مکزیکوسیتی» (Metropolitan Catedral)، «کاخ ریاست جمهوری لا موندا» (La Moneda Presidential Palace) و خانه «پابلو نرودا» (Pablo Neruda) در آن قرار دارند.

Comuna of Santiago

اکنون، با بهره‌گیری از کد زیر، نگاهی به ساختار داده سانتیاگو می‌شود.

1sf.records()[25]

خروجی:

Out:

[‘13’,
‘131’,
‘13101’,
‘REGIÓN METROPOLITANA DE SANTIAGO’,
‘SANTIAGO’,
‘SANTIAGO’]

می توان مشاهده کرد که برخی از داده‌ها تغییر کرده‌اند و مهم‌تر آنکه نام شهر اکنون «SANTIAGO» است.

5. تبدیل داده‌های shapefile در دیتافریم Pandas

در مثال آخر، نگارنده این مطلب از پیش می‌دانسته که ID شهر سانتیاگو برابر با ۲۵ است.

اما چگونه می‌توان این id را با شروع از نام آن شهر به دست آورد؟ ابتدا باید یک تابع مفید برای تبدیل فرمت «shapefile» به یک فرمت متداول‌تر Pandas پیدا کرد.

1def read_shapefile(sf):
2    """
3    Read a shapefile into a Pandas dataframe with a 'coords' 
4    column holding the geometry information. This uses the pyshp
5    package
6    """
7    fields = [x[0] for x in sf.fields][1:]
8    records = sf.records()
9    shps = [s.points for s in sf.shapes()]
10    df = pd.DataFrame(columns=fields, data=records)
11    df = df.assign(coords=shps)
12    return df

اکنون، باید داده‌های sf را روی یک دیتافریم تبدیل، و بررسی کرد که چگونه به نظر می‌رسد.

1df = read_shapefile(sf)
2df.shape

دیتا فریم دارای شکل (52, 7) است. این یعنی ۷ ویژگی متفاوت (ستون) برای هر خط (comuna) وجود دارد. شایان توجه است که پیش‌تر، ۶ مورد از آن‌ها مشاهده شدند. به نظر می‌رسد یک مورد دیگر اکنون اضافه شده است. در ادامه نمونه‌ای ارائه شده:

1df.sample(5)

دیتافریم در Pandas

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

چگونه می‌توان ID شهر Santiago را به دست آورد؟ با استفاده از کتابخانه Pandas این کار بسیار آسان است.

1df[df.NOM_COMUNA == ‘SANTIAGO’]

می‌توان به سادگی مشاهده کرد که ۲۵ دقیقا اندیس دیتافریم و جایی که شهر در آن قرار گرفته است. با دستور ساده‌ای از Pandas می‌توان اندیس (یا ID) را همراه با نام شهر دریافت کرد.

1df.NOM_COMUNA

خروجی:

Out:
0 LAS CONDES
1 LO BARNECHEA
2 VITACURA
3 HUECHURABA
4 PUDAHUEL
…
49 ALHUÉ
50 LAMPA
51 TILTIL

۶. ترسیم یک شکل خاص

در نهایت، می‌توان مشاهده کرد که shape دقیقا چیست. برای این کار، باید تابعی برای ترسیم آن ساخت.

از کتابخانه پایتون MatPlotLib برای انجام این کار استفاده می‌شود.

1def plot_shape(id, s=None):
2    """ PLOTS A SINGLE SHAPE """
3    plt.figure()
4    ax = plt.axes()
5    ax.set_aspect('equal')
6    shape_ex = sf.shape(id)
7    x_lon = np.zeros((len(shape_ex.points),1))
8    y_lat = np.zeros((len(shape_ex.points),1))
9    for ip in range(len(shape_ex.points)):
10        x_lon[ip] = shape_ex.points[ip][0]
11        y_lat[ip] = shape_ex.points[ip][1]
12    plt.plot(x_lon,y_lat) 
13    x0 = np.mean(x_lon)
14    y0 = np.mean(y_lat)
15    plt.text(x0, y0, s, fontsize=10)
16    # use bbox (bounding box) to set plot limits
17    plt.xlim(shape_ex.bbox[0],shape_ex.bbox[2])
18    return x0, y0

تابع بالا دو کار انجام می‌دهد:

  • ترسیم شکل (چندضلعی) بر پایه مختصات‌های شهرها
  • محاسبه و بازگرداندن «نقطه متوسط» (Medium Point) آن شکل خاص (x0, y0)

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

ترسیم نقشه جغرافیایی در پایتون

لازم به توجه است که برای ترسیم یک شکل، باید ID آن را دانست. البته در کد بالا، از نام شهر (SANTIAGO) برای انجام این کار استفاده شد. استفاده از Pandas برای محاسبه ID کار ساده‌ای بود که پیش‌تر توضیح داده شد و می‌توان خط دوم کد بالا را با کد مربوط به این کار جایگزین کرد.

۷. ترسیم یک نقشه کامل

ترسیم یک شکل تنها اساسا به منظور کار کردن با بخش کوچکی از کد است.

1sf.shape(id)

اکنون، باید همه اشکالی که در دیتافریم موجود هستند در تصویر مشابهی ترسیم شوند.

1def plot_map(sf, x_lim = None, y_lim = None, figsize = (11,9)):
2    '''
3    Plot map with lim coordinates
4    '''
5    plt.figure(figsize = figsize)
6    id=0
7    for shape in sf.shapeRecords():
8        x = [i[0] for i in shape.shape.points[:]]
9        y = [i[1] for i in shape.shape.points[:]]
10        plt.plot(x, y, 'k')
11        
12        if (x_lim == None) & (y_lim == None):
13            x0 = np.mean(x)
14            y0 = np.mean(y)
15            plt.text(x0, y0, id, fontsize=10)
16        id = id+1
17    
18    if (x_lim != None) & (y_lim != None):     
19        plt.xlim(x_lim)
20        plt.ylim(y_lim)

تابع بالا، به طور پیش‌فرض، همه اشکال روی فایل df را به همراه ID هر شکل در میان آن ترسیم می‌کند. همچنین، می‌توان یک نقشه بزرگ‌نمایی شده را ترسیم کرد. می‌توان کد را به گونه‌ای تغییر داد که ID‌ها را پرینت کند یا نکند.

ترسیم یک نقشه کامل

1plot_map(sf)

ترسیم نقشه جغرافیایی در پایتون

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

1y_lim = (-33.7,-33.3) # latitude 
2x_lim = (-71, -70.25) # longitude
3plot_map(sf, x_lim, y_lim)

ترسیم نقشه جغرافیایی در پایتون

۸. ترسیم یک شکل در نمودار کامل

می‌توان دو تابع پیشین را «ادغام» (merge) و یک شکل تنها را درون نمودار کامل «ترسیم» (plot) کرد.

بدین منظور، باید یک تابع جدید نوشت که شماره محل در آن پارامتر ورودی است.

1def plot_map2(id, sf, x_lim = None, y_lim = None, figsize=(11,9)):
2    '''
3    Plot map with lim coordinates
4    '''
5   
6    plt.figure(figsize = figsize)
7    for shape in sf.shapeRecords():
8        x = [i[0] for i in shape.shape.points[:]]
9        y = [i[1] for i in shape.shape.points[:]]
10        plt.plot(x, y, 'k')
11        
12    shape_ex = sf.shape(id)
13    x_lon = np.zeros((len(shape_ex.points),1))
14    y_lat = np.zeros((len(shape_ex.points),1))
15    for ip in range(len(shape_ex.points)):
16        x_lon[ip] = shape_ex.points[ip][0]
17        y_lat[ip] = shape_ex.points[ip][1]
18    plt.plot(x_lon,y_lat, 'r', linewidth=3) 
19    
20    if (x_lim != None) & (y_lim != None):     
21        plt.xlim(x_lim)
22        plt.ylim(y_lim)

ترسیم شهر سانتیاگو به رنگ قرمز:

1plot_map2(25, sf, x_lim, y_lim)

ترسیم نمودار جغرافیایی در پایتون

برای «پُر» (fill) کردن یک شکل کامل با یک رنگ خاص می‌توان از plt.fill استفاده کرد. تابع را می‌توان به صورت زیر بازنویسی کرد.

1def plot_map_fill(id, sf, x_lim = None, 
2                          y_lim = None, 
3                          figsize = (11,9), 
4                          color = 'r'):
5    '''
6    Plot map with lim coordinates
7    '''
8    
9    plt.figure(figsize = figsize)
10    fig, ax = plt.subplots(figsize = figsize)
11    for shape in sf.shapeRecords():
12        x = [i[0] for i in shape.shape.points[:]]
13        y = [i[1] for i in shape.shape.points[:]]
14        ax.plot(x, y, 'k')
15        
16    shape_ex = sf.shape(id)
17    x_lon = np.zeros((len(shape_ex.points),1))
18    y_lat = np.zeros((len(shape_ex.points),1))
19    for ip in range(len(shape_ex.points)):
20        x_lon[ip] = shape_ex.points[ip][0]
21        y_lat[ip] = shape_ex.points[ip][1]
22    ax.fill(x_lon,y_lat, color)
23    
24    if (x_lim != None) & (y_lim != None):     
25        plt.xlim(x_lim)
26        plt.ylim(y_lim)

ترسیم شهر Las Condes (که ID = 0) به رنگ سبز (g) با استفاده از قطعه کد زیر انجام می‌شود.

1plot_map_fill(0, sf, x_lim, y_lim, color='g')

۹. ترسیم چندین شکل روی یک نقشه کامل

گام بعدی در «سفر دشوار ترسیم نقشه»، ساخت چندین شکل انتخابی است. برای این کار، به جای داشتن یک ID به عنوان پارامتر ورودی، لیستی از ID‌ها وجود دارد و یک حلقه for برای پر کردن هر یک از آن‌ها با رنگ استفاده می‌شود.

تابع ویرایش شده به صورت زیر است.

1def plot_map_fill_multiples_ids(title, comuna, sf, 
2                                               x_lim = None, 
3                                               y_lim = None, 
4                                               figsize = (11,9), 
5                                               color = 'r'):
6    '''
7    Plot map with lim coordinates
8    '''
9    
10    plt.figure(figsize = figsize)
11    fig, ax = plt.subplots(figsize = figsize)
12    fig.suptitle(title, fontsize=16)
13    for shape in sf.shapeRecords():
14        x = [i[0] for i in shape.shape.points[:]]
15        y = [i[1] for i in shape.shape.points[:]]
16        ax.plot(x, y, 'k')
17            
18    for id in comuna:
19        shape_ex = sf.shape(id)
20        x_lon = np.zeros((len(shape_ex.points),1))
21        y_lat = np.zeros((len(shape_ex.points),1))
22        for ip in range(len(shape_ex.points)):
23            x_lon[ip] = shape_ex.points[ip][0]
24            y_lat[ip] = shape_ex.points[ip][1]
25        ax.fill(x_lon,y_lat, color)
26             
27        x0 = np.mean(x_lon)
28        y0 = np.mean(y_lat)
29        plt.text(x0, y0, id, fontsize=10)
30    
31    if (x_lim != None) & (y_lim != None):     
32        plt.xlim(x_lim)
33        plt.ylim(y_lim)

در تابع بالا، «comuna» (شهر) اکنون لیستی از ID‌ها است.

1comuna_id = [0, 1, 2, 3, 4, 5, 6]
2plot_map_fill_multiples_ids("Multiple Shapes", 
3                            comuna_id, sf, color = 'r')

ترسیم نقشه در پایتون

با استفاده از فرصتی که دیتافریم Pandas پیشین فراهم کرده، می‌توان تابع ساده‌ای ساخت که ورودی آن نام comuna است به جای آنکه ID آن باشد.

1def plot_comunas_2(sf, title, comunas, color):
2    '''
3    Plot map with selected comunes, using specific color
4    '''
5    
6    df = read_shapefile(sf)
7    comuna_id = []
8    for i in comunas:
9        comuna_id.append(df[df.NOM_COMUNA == i.upper()]
10                         .index.get_values()[0])
11    plot_map_fill_multiples_ids(title, comuna_id, sf, 
12                                       x_lim = None, 
13                                       y_lim = None, 
14                                       figsize = (11,9), 
15                                       color = color);

ترسیم «شهرهای جنوبی» (southern comunes) از Santiago Metropolitan Region با استفاده از کدهای زیر انجام می‌شود.

1south = ['alhué', 'calera de tango', 'buin', 'isla de maipo', 'el bosque', 'paine', 'la granja', 'pedro aguirre cerda', 'lo espejo', 'puente alto', 'san joaquín', 'san miguel', 'pirque', 'san bernardo', 'san ramón', 'la cisterna', 'talagante', 'la pintana']
2plot_comunas_2(sf, 'South', south, 'c')

ترسیم نقشه در پایتون

۱۰. ساخت نقشه‌های گرمایی

یک نوع بسیار پر کاربرد از نقشه، پر کردن شکل خاص یا یک رنگ به صورتی است که «شدت» آن متناسب با یک مقداری معین است. در این راستا، می‌توان یک رویکرد کلی روی توزیع داده‌ها در یک ناحیه جغرافیایی -برای مثال توزیع جمعیت - داشت. انجام این کار، با داشتن یک چشم‌انداز کلی پیرامون توزیع داده‌ها روی یک ناحیه جغرافیایی مشخص است.

در این راستا، ابتدا تابعی ساخته می‌شود که با دریافت لیست داده، آن‌ها را به «رده‌هایی» (bins) تقسیم می‌کند. به هر یک از این رده‌ها یک رنگ خاص تخصیص داده می‌شود. بر اساس تجربه، معمولا داشتن ۵ الی ۷ رده برای داشتن حس خوبی از توزیع داده‌ها مناسب است. در اینجا از ۶ رده و ۴ پالت رنگ متفاوت مرتبط با رده‌ها استفاده می‌شود. در زمان باید یکی از این رده‌ها انتخاب شوند.

1def calc_color(data, color=None):
2        if color   == 1: color_sq =  
3                        ['#dadaebFF','#bcbddcF0','#9e9ac8F0',
4                        '#807dbaF0','#6a51a3F0','#54278fF0']; 
5                        colors = 'Purples';
6        elif color == 2: color_sq = 
7                        ['#c7e9b4','#7fcdbb','#41b6c4',
8                        '#1d91c0','#225ea8','#253494']; 
9                        colors = 'YlGnBu';
10        elif color == 3: color_sq = 
11                        ['#f7f7f7','#d9d9d9','#bdbdbd',
12                        '#969696','#636363','#252525']; 
13                        colors = 'Greys';
14        elif color == 9: color_sq = 
15                        ['#ff0000','#ff0000','#ff0000',
16                        '#ff0000','#ff0000','#ff0000']
17        else:            color_sq = 
18                        ['#ffffd4','#fee391','#fec44f',
19                        '#fe9929','#d95f0e','#993404']; 
20                        colors = 'YlOrBr';
21        new_data, bins = pd.qcut(data, 6, retbins=True, 
22        labels=list(range(6)))
23        color_ton = []
24        for val in new_data:
25            color_ton.append(color_sq[val]) 
26        if color != 9:
27            colors = sns.color_palette(colors, n_colors=6)
28            sns.palplot(colors, 0.6);
29            for i in range(6):
30                print ("\n"+str(i+1)+': '+str(int(bins[i]))+
31                       " => "+str(int(bins[i+1])-1), end =" ")
32            print("\n\n   1   2   3   4   5   6")    
33        return color_ton, bins;

هر دو تابع ()plot_comunas و plot_map_fill_multiples_ids باید برای استفاده از مزایای این طرح رنگی سازگار شوند.

1def plot_comunas_data(sf, title, comunas, data=None, 
2                      color=None, print_id=False):
3    '''
4    Plot map with selected comunes, using specific color
5    '''
6    
7    color_ton, bins = calc_color(data, color)
8    df = read_shapefile(sf)
9    comuna_id = []
10    for i in comunas:
11        i = conv_comuna(i).upper()
12        comuna_id.append(df[df.NOM_COMUNA == 
13                            i.upper()].index.get_values()[0])
14    plot_map_fill_multiples_ids_tone(sf, title, comuna_id, 
15                                     print_id, 
16                                     color_ton, 
17                                     bins, 
18                                     x_lim = None, 
19                                     y_lim = None, 
20                                     figsize = (11,9));

و:

1def plot_map_fill_multiples_ids_tone(sf, title, comuna,  
2                                     print_id, color_ton, 
3                                     bins, 
4                                     x_lim = None, 
5                                     y_lim = None, 
6                                     figsize = (11,9)):
7    '''
8    Plot map with lim coordinates
9    '''
10        
11    plt.figure(figsize = figsize)
12    fig, ax = plt.subplots(figsize = figsize)
13    fig.suptitle(title, fontsize=16)
14for shape in sf.shapeRecords():
15        x = [i[0] for i in shape.shape.points[:]]
16        y = [i[1] for i in shape.shape.points[:]]
17        ax.plot(x, y, 'k')
18            
19    for id in comuna:
20        shape_ex = sf.shape(id)
21        x_lon = np.zeros((len(shape_ex.points),1))
22        y_lat = np.zeros((len(shape_ex.points),1))
23        for ip in range(len(shape_ex.points)):
24            x_lon[ip] = shape_ex.points[ip][0]
25            y_lat[ip] = shape_ex.points[ip][1]
26        ax.fill(x_lon,y_lat, color_ton[comuna.index(id)])
27        if print_id != False:
28            x0 = np.mean(x_lon)
29            y0 = np.mean(y_lat)
30            plt.text(x0, y0, id, fontsize=10)
31    if (x_lim != None) & (y_lim != None):     
32        plt.xlim(x_lim)
33        plt.ylim(y_lim)

به منظور ارزیابی تابع جدید، لیست قبلی اشکال برای نواحی جنوبی سانتیاگو دریافت می‌شود، یک مقدار عمومی به هر یک از آن‌ها تخصیص داده می‌شود. از «('color pallete #1 ('Purples» در این راستا استفاده می‌شود.

1south = ['alhué', 'calera de tango', 'buin', 'isla de maipo', 'el bosque', 'paine', 'la granja', 'pedro aguirre cerda', 'lo espejo', 'puente alto', 'san joaquín', 'san miguel', 'pirque', 'san bernardo', 'san ramón', 'la cisterna', 'talagante', 'la pintana']
2data = [100, 2000, 300, 400000, 500, 600, 100, 2000, 300, 400, 500, 600, 100, 2000, 300, 400, 500, 600]
3print_id = True # The shape id will be printed
4color_pallete = 1 # 'Purples'
5plot_comunas_data(sf, 'South', south, data, color_pallete, print_id)

ترسیم نقشه گرمایی در پایتون

۱۱. ترسیم داده‌های واقعی

برای پایان راهنمای چگونگی ترسیم نقشه در پایتون، از داده‌های واقعی مربوط به آخرین سرشماری سال ۲۰۱۷ شیلی استفاده و تابع‌های ساخته شده در بخش پیشین روی آن اعمال می‌شوند.

خواندن مجموعه داده

1census_17 = pd.read_excel('./data/CENSO_2017_COMUNAS_RM.xlsx')
2census_17.shape
3Out:
4(52,7)

مجموعه داده دارای ۵۲ خط است و هنگامی معنا می‌دهد که هر خط شامل داده‌های مرتبط با هر یک از شهرهای سانتیاگو باشد.

ترسیم نقشه در پایتون

برای مثال، ستون «PERSONAS» مرتبط با تعداد افرادی است که در هر شهر زندگی می‌کنند. «TOTAL_VIV» تعداد کل خانه‌ها در آن شهر است.

ترسیم نمودار

اکنون تابع‌های نقشه برای تحلیل چگونگی توزیع جمعیت در ناحیه Santiago Metropolitan مورد استفاده قرار می‌گیرند.

1title = 'Population Distrubution on Santiago Metropolitan Region'
2data = census_17.PERSONAS
3names = census_17.NOM_COMUNA
4plot_comunas_data(sf, title, names, data, 4, True)

ترسیم نقشه در پایتون

می‌توان مشاهده کرد که جمعیت به شدت حول محور ناحیه مرکزی Metropolitan توزیع شده. به سمت شرق (سمت راست روی نقشه) جمعیت تُنُک است و این موضوع با توجه به اینکه در آن منطقه کوه‌های Andes واقع شده منطقی محسوب می‌شود. به سمت غرب و جنوب نواحی کشاورزی قرار دارند. یک گام دیگر ترسیم درصد مهاجرت‌کنندگان نسبت به کل جمعیت Metropolitan Region در سانتیاگو است.

1title = 'Percentual of immigrants over total population'
2data = census_17.INM_PERC
3names = census_17.NOM_COMUNA
4plot_comunas_data(sf, title, names, data, 2, True)

ترسیم نمودار گرمایی در پایتون

۱۲. نتیجه‌گیری

در پایان می‌توان فهمید که ساخت نقشه با استفاده از سه تابع توسعه داده شده در این راهنما، تنها با یک خط از کد امکان‌پذیر است.

1plot_comunas_data() .... that calls:
2plot_map_fill_multiples_ids_tone() ... that calls:
3calc_color()

آنچه در این مطلب توسعه داده شده، برای ناحیه Santiago Matropolitan است، که می‌توان به سادگی آن را برای استفاده با هر نقشه برداری موجود در اینترنتی سازگار کرد. برای مثال، می‌توان به «US Census Bureau» (+) رفت و Cartographic Boundary Shapefiles را برای ایالت‌های آمریکا دانلود کرد. کد زیر برای سانتیاگو است:

1shp_path = "./cb_2017_us_state_5m/cb_2017_us_state_5m.shp"
2sf = shp.Reader(shp_path)
3# Continental US
4y_lim = (23, 50) # lat 
5x_lim = (-128, -65) # long
6state_id = [0, 10, 3, 5, 6, 7, 8, 30]
7plot_map_fill_multiples_ids("US - States", state_id, sf, x_lim, 
8                             y_lim, color = 'r', figsize = (15,9))

که می‌توان آن را ترسیم کرد:

ترسیم نقشه در پایتون

Jupyter Notebook و همه داده‌های مورد استفاده در این مقاله از گیت‌هاب (+) قابل دانلود هستند.

اگر مطلب بالا برای شما مفید بوده، آموزش‌های زیر نیز به شما پیشنهاد می‌شود:

^^

بر اساس رای ۷ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
Medium
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *