Hướng dẫn dùng subplot title python

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 2x2

>>> 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()

>>>

Hướng dẫn dùng subplot title python

Mặc dù cách tiếp cận trước đó có thể chấp nhận được, nhưng theo tiếp cận hướng đối tượng bằng cách sử dụng các thể hiện của lớp figure. Chúng tôi chứng minh điều này bằng cách viết lại ví dụ trước. Trong trường hợp này, chúng ta phải sử dụng phương thức "add_subplot" cho đối tượ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()

>>>

Để loại bỏ, hay tùy biến ticks trong các subplot, với cách tiếp cận đầu tiên ta có thể sử dụng phương thức 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 thức set_xticks(), và set_yticks() của lớp Axes trả về từ phương thức add_subplot(). Các bạn tự thực hành phần này nhé.

Các bạn đoán thử xem làm thế nào tôi có thể tạo được một figure với cách bố trí các subplots như sau: (các bạn chú ý phần màu tôi đã trình bầy trong lời giải sẽ giúp các bạn hiểu về cách chia blocks)

Bài 1:

Hướng dẫn dùng subplot title python

Lời giải tham khảo:

>>> 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:

Hướng dẫn dùng subplot title python

Lời giải tham khảo:

>>> 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:

Hướng dẫn dùng subplot title python

Lời giải tham khảo:

>>> 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 1x1

>>> 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()

>>>

Hướng dẫn dùng subplot title python

Chúng ta có thể sử dụng một số thông số của Gridspec, ví dụ: Chúng ta có thể xác định rằng biểu đồ của chúng ta sẽ bắt đầu ở 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()

 

Hướng dẫn dùng subplot title python

Ví dụ tiếp theo cho thấy một 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()

Hướng dẫn dùng subplot title python

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

Hướng dẫn dùng subplot title python

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 lời giải 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ất cả các số lượng nằm trong các 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()
>>>
 
Hướng dẫn dùng subplot title python
 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()
Hướng dẫn dùng subplot title python

Kết Luận

Qua bài học bạn có thể chia hình vẽ thành nhiều 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á nhân thì gridspec giúp việc này dễ dàng hơn đặc biệt với trường hợp có layout phức tạp. Trên mỗi một cửa sổ (subplot) bạn có thể tương tác qua đối tượng Axis được trả về khi sử dụng subplot và Gridspec.