Chi tiết bài học 4. Multiple Subplots

4. Multiple Subplots

Chúng ta đã đưa ra rất nhiều ví dụ để vẽ đồ thị trong các chương trước của hướng dẫn Python trên Matplotlib. Một câu hỏi thường gặp là làm thế nào để có nhiều plots trong một đồ thị?

Trong trường hợp đơn giản nhất điều này có thể có nghĩa là, bạn có một đường cong và bạn muốn một đường cong in qua nó. Đây không phải là một vấn đề, bởi vì nó sẽ đủ để đưa haiplots trong kịch bản của bạn, như chúng ta đã thấy trước đây. Trường hợp thú vị hơn là, nếu bạn muốn hai plots trong một cửa sổ. Trong một cửa sổ có nghĩa là chúng phải ở hai vị trí con riêng lẻ, nghĩa là không được in trên nhau. Ý tưởng là có nhiều hơn một đồ thị trong một cửa sổ và mỗi đồ thị xuất hiện trong subplot riêng của mình.

Chúng tôi sẽ trình bày hai cách khác nhau để hoàn thành mục tiêu này:

    subplot
    gridspec

Chúng tôi nghĩ rằng gridspec là lựa chọn tốt nhất vì nó dễ sử dụng hơn rất nhiều, nếu bố cục phức tạp hơn!

Subplot: Làm việc với nhiều figures và axes

Cú pháp: subplot(nrows, ncols, plot_number)

Nếu một subplot được áp dụng cho một con số, con số này sẽ được chia thành các trục con ‘nrows’ * ‘ncols’. Tham số ‘plot_number’ xác định subplot mà hàm phải tạo ra. ‘plot_number’ có thể dao động từ 1 đến tối đa là ‘nrows’ * ‘ncols’.

Nếu các giá trị của ba tham số nhỏ hơn 10, thì hàm subplot có thể được gọi với một tham số int, trong đó hàng trăm đại diện cho ‘nrows’, hàng chục đại diện cho ‘ncols’ vàhàng đơn vị biểu diễn ‘plot_number’. Điều này có nghĩa là: Thay vì subplot (2, 3, 4) chúng ta có thể viết subplot (234).

Ví dụ sau đây tạo ra hai subplot của lưới 2×2

>>> import matplotlib.pyplot as plt

>>> python_course_green = "#476042"

>>> plt.figure(figsize=(6, 4))



>>> plt.subplot(221) # equivalent to: plt.subplot(2, 2, 1)



>>> plt.text(0.5, # x coordinate, 0 leftmost positioned, 1 rightmost

...          0.5, # y coordinate, 0 topmost positioned, 1 bottommost

...          'subplot(2,2,1)', # the text which will be printed

...          horizontalalignment='center', # shortcut 'ha'

...          verticalalignment='center', # shortcut 'va'

...          fontsize=20, # can be named 'font' as well

...          alpha=.5 # float (0.0 transparent through 1.0 opaque)

...          )



>>> plt.subplot(224, axisbg=python_course_green)

C:\ProgramData\Anaconda2\lib\site-packages\matplotlib\cbook.py:136: MatplotlibDeprecationWarning: The axisbg attribute was deprecated in version 2.0. Use facecolor instead.

  warnings.warn(message, mplDeprecation, stacklevel=1)



>>> plt.text(0.5, 0.5,

...          'subplot(2,2,4)',

...          ha='center', va='center',

...          fontsize=20,

...          color="y")



>>> plt.show()

>>>

Mặc dù cách tiếp cận trước đó hoàn toàn có thể đồng ý được, nhưng theo tiếp cận hướng đối tượng người tiêu dùng bằng cách sử dụng những biểu lộ của lớp figure. Chúng tôi chứng tỏ điều này bằng cách viết lại ví dụ trước. Trong trường hợp này, tất cả chúng ta phải sử dụng phương pháp ” add_subplot ” cho đối tượng người dùng figure .

>>> import matplotlib.pyplot as plt

>>> python_course_green = "#476042"

>>> fig = plt.figure(figsize=(6, 4))

>>> sub1 = fig.add_subplot(221) # equivalent to: plt.subplot(2, 2, 1)

>>> sub1.text(0.5, # x coordinate, 0 leftmost positioned, 1 rightmost

...           0.5, # y coordinate, 0 topmost positioned, 1 bottommost

...           'subplot(2,2,1)', # the text which will be printed

...           horizontalalignment='center', # shortcut 'ha'

...           verticalalignment='center', # shortcut 'va'

...           fontsize=20, # can be named 'font' as well

...           alpha=.5 # float (0.0 transparent through 1.0 opaque)

...           )



>>> sub2 = fig.add_subplot(224, axisbg=python_course_green)

>>> sub2.text(0.5, 0.5,

...           'subplot(2,2,4)',

...           ha='center', va='center',

...           fontsize=20,

...           color="y")



>>> plt.show()

>>>

Để vô hiệu, hay tùy biến ticks trong những subplot, với cách tiếp cận tiên phong ta hoàn toàn có thể sử dụng phương pháp xticks, yticks ( ) của lớp pyplot, tuy nhiên cách sử dụng OOP ở ví dụ thứ hai ta cần sử dụng phương pháp set_xticks ( ), và set_yticks ( ) của lớp Axes trả về từ phương pháp add_subplot ( ). Các bạn tự thực hành thực tế phần này nhé .
Các bạn đoán thử xem làm thế nào tôi hoàn toàn có thể tạo được một figure với cách sắp xếp những subplots như sau : ( những bạn chú ý quan tâm phần màu tôi đã trình bầy trong giải thuật sẽ giúp những bạn hiểu về cách chia blocks )
Bài 1 :

Lời giải tìm hiểu thêm :

>>> import  matplotlib.pyplot as plt

>>> X = [ (2,1,1), (2,3,4), (2,3,5), (2,3,6) ]

>>> for nrows, ncols, plot_number in X:

...     plt.subplot(nrows, ncols, plot_number)

...









>>> plt.show()

Bài 2 :

Lời giải tìm hiểu thêm :

>>> import  matplotlib.pyplot as plt

>>> X = [ (2,3,1),(2,3,2), (2,3,3),(2,1,2)]

>>>

>>> for nrows, ncols, plot_number in X:

...     plt.subplot(nrows, ncols, plot_number)

...









>>> plt.show()

>>>

Bài 3 :

Lời giải tìm hiểu thêm :

>>> import  matplotlib.pyplot as plt

>>> X = [  (4,2,1),(4,2,2), (4,2,3), (4,2,5), (4,2,(4,6)), (4,1,4) ]

>>> plt.subplots_adjust(bottom=0.05, left=0.05, top = 0.975, right=0.95)

>>>

>>> for nrows, ncols, plot_number in X:

...     plt.subplot(nrows, ncols, plot_number)

...













>>> plt.show()

Dùng gridspec để vẽ subplots.

‘Matplotlib.gridspec’ chứa một lớp GridSpec. Nó có thể được sử dụng như là một thay thế cho subplot để xác định hình học của subplots được tạo ra. Ý tưởng cơ bản đằng sau GridSpec là một ‘lưới’. Một lưới được thiết lập với số hàng và cột. Chúng ta phải xác định sau này, bao nhiêu lưới mà một subplot nên phủ.

Ví dụ sau cho thấy trường hợp nhỏ hoặc đơn giản nhất, tức là lưới 1×1

>>> import matplotlib.pyplot as plt

>>> from matplotlib.gridspec import GridSpec

>>> fig = plt.figure()

>>> gs = GridSpec(1, 1)

>>> ax = fig.add_subplot(gs[0,0])

>>> plt.show()

>>>

Chúng ta hoàn toàn có thể sử dụng 1 số ít thông số kỹ thuật của Gridspec, ví dụ : Chúng ta hoàn toàn có thể xác lập rằng biểu đồ của tất cả chúng ta sẽ mở màn ở mức 20 % từ đáy và 15 % ở phía bên trái của vùng hình có sẵn :

>>> import matplotlib.pyplot as plt

>>> from matplotlib.gridspec import GridSpec

>>> fig = plt.figure()

>>> gs = GridSpec(1, 1,

...               bottom=0.2,

...               left=0.15,

...               top=0.8)

>>> ax = fig.add_subplot(gs[0,0])

>>> plt.show()

 

Ví dụ tiếp theo cho thấy một phong cách thiết kế lưới phức tạp hơn :

>>> import matplotlib.gridspec as gridspec

>>> import matplotlib.pyplot as pl

>>> pl.figure(figsize=(6, 4))



>>> G = gridspec.GridSpec(3, 3)

>>> axes_1 = pl.subplot(G[0, :])

>>> pl.text(0.5, 0.5, 'Axes 1', ha='center', va='center', size=24, alpha=.5)



>>> axes_2 = pl.subplot(G[1, :-1])

>>> pl.text(0.5, 0.5, 'Axes 2', ha='center', va='center', size=24, alpha=.5)



>>> axes_3 = pl.subplot(G[1:, -1])

>>> pl.text(0.5, 0.5, 'Axes 3', ha='center', va='center', size=24, alpha=.5)



>>> axes_4 = pl.subplot(G[-1, 0])

>>> pl.text(0.5, 0.5, 'Axes 4', ha='center', va='center', size=24, alpha=.5)



>>> axes_5 = pl.subplot(G[-1, -2])

>>> pl.text(0.5, 0.5, 'Axes 5', ha='center', va='center', size=24, alpha=.5)



>>> pl.tight_layout()

>>> pl.show()

Bài tập hãy tạo ra một figure có những subplot theo hình sau :

Lời giải :

>>> import matplotlib.gridspec as gridspec

>>> import matplotlib.pyplot as pl

>>> pl.figure(figsize=(6, 4))



>>> G = gridspec.GridSpec(3, 3)

>>> axes_1 = pl.subplot(G[0, :])

>>> axes_2 = pl.subplot(G[1:,0])

>>> axes_3 = pl.subplot(G[1, 1:])

>>> axes_4 = pl.subplot(G[-1, 1:])

>>> pl.tight_layout()

>>> pl.show()

Bạn nhận thấy giải thuật khi sử dụng gridspec dễ hiểu hơn đúng không !
Vẽ một plot bên trong một plot khác .

Ta dùng add_axes(*args, **kwargs) của lớp figure.

Thêm một trục tại vị trí rect [ trái, dưới, chiều rộng, chiều cao ] nơi mà tổng thể những số lượng nằm trong những phân số của chiều rộng và chiều cao .

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> fig = plt.figure()
>>> X = [1, 2, 3, 4, 5, 6, 7]
>>> Y = [1, 3, 4, 2, 5, 8, 6]
>>> axes1 = fig.add_axes([0.1, 0.1, 0.9, 0.9]) # main axes
>>> axes2 = fig.add_axes([0.2, 0.6, 0.4, 0.3]) # inset axes
>>> # main figure
... axes1.plot(X, Y, 'r')
[]
>>> axes1.set_xlabel('x')

>>> axes1.set_ylabel('y')

>>> axes1.set_title('title')

>>> # insert
... axes2.plot(Y, X, 'g')
[]
>>> axes2.set_xlabel('y')

>>> axes2.set_ylabel('x')

>>> axes2.set_title('title inside')

>>>
>>> plt.show()
>>>

 

Có thể định cấu hình các dãy của các trục. Điều này có thể được thực hiện bằng cách sử dụng phương thức set_ylim() và set_xlim() trong đối Axis.


>>> import numpy as np

>>> import matplotlib.pyplot as plt

>>> fig, axes = plt.subplots(1, 3, figsize=(10, 4))

>>> x = np.arange(0, 5, 0.25)

>>> axes[0].plot(x, x**2, x, x**3)

[, ]

>>> axes[0].set_title("default axes ranges")



>>> axes[1].plot(x, x**2, x, x**3)

[, ]

>>> axes[1].axis('tight')

(-0.23750000000000002, 4.9874999999999998, -5.3585937500000007, 112.53046875)

>>> axes[1].set_title("tight axes")



>>> axes[2].plot(x, x**2, x, x**3)

[, ]

>>> axes[2].set_ylim(0, 60)

(0, 60)

>>> axes[2].set_xlim(2, 5)

(2, 5)

>>> axes[2].set_title("custom axes range");



>>> plt.show()

Kết Luận

Qua bài học kinh nghiệm bạn hoàn toàn có thể chia hình vẽ thành nhiều hành lang cửa số con theo một layout mà bạn muốn qua hai cách subplot và gridspec, theo cảm nhận riêng của cá thể thì gridspec giúp việc này thuận tiện hơn đặc biệt quan trọng với trường hợp có layout phức tạp. Trên mỗi một hành lang cửa số ( subplot ) bạn hoàn toàn có thể tương tác qua đối tượng người tiêu dùng Axis được trả về khi sử dụng subplot và Gridspec .