Phần 19: Contour Plot ( Đồ thị đường bao ) – Matplotib Basic
1. Khái niệm căn bản
Đồ thị đường bao (đôi lúc được gọi là Đồ thị mức) là 1 cách để thể hiện 1 bề mặt ba chiều trên 1 mặt phẳng 2 chiều. Nó vẽ biểu đồ 2 biến dự báo X Y trên trục y và 1 biến phản ứng Z dưới dạng các đường bao. Những đường bao này đôi lúc được gọi là z-slice hay giá trị iso-response.
1 đồ thị đường bao là thích hợp nếu như bạn cần xem đường viền Z thay đổi ra sao dưới dạng hàm của 2 đầu vào X và Y, sao cho Z = f (X, Y). Đường đồng mức hay đường cô lập của hàm 2 biến là 1 đường cong mà hàm có giá trị không thay đổi.
Các biến độc lập x và y thường bị giới hạn trong 1 lưới bình thường gọi là meshgrid. Numpy.meshgrid tạo nên 1 lưới hình chữ nhật từ 1 mảng những giá trị x và 1 mảng những giá trị y.
API Matplotlib chứa hàm contour () và contourf () để vẽ đường đồng mức và đường bao đã tô tương ứng. Cả 2 hàm đều cần ba tham số x, y và z.
import numpy as np
import matplotlib.pyplot as plt
xlist = np.linspace(-3.0, 3.0, 100)
ylist = np.linspace(-3.0, 3.0, 100)
X, Y = np.meshgrid(xlist, ylist)
Z = np.sqrt(X**2 + Y**2)
fig,ax=plt.subplots(1,1)
cp = ax.contourf(X, Y, Z)
fig.colorbar(cp) # Add a colorbar to a plot
ax.set_title('Filled Contours Plot')
#ax.set_xlabel('x (cm)')
ax.set_ylabel('y (cm)')
plt.present()
2. Ví dụ minh hoạ :
Ví dụ 1 :
Import các thư viện cần thiết :
import matplotlib
import numpy as np
import matplotlib.ticker as ticker
import matplotlib.pyplot as plt
Định nghĩa những giá trị :
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2
Tạo nhãn đường viền bằng việc dùng các class float như dưới đây :
# Define a category that forces illustration of float to look a sure approach
# This take away trailing zero so '1.0' turns into '1'
class nf(float):
def __repr__(self):
s = f'{self:.1f}'
return f'{self:.0f}' if s[-1] == '0' else s
# Basic contour plot
fig, ax = plt.subplots()
CS = ax.contour(X, Y, Z)
# Recast ranges to new class
CS.ranges = [nf(val) for val in CS.levels]
# Label ranges with specifically formatted floats
if plt.rcParams["text.usetex"]:
fmt = r'%r %%'
else:
fmt = '%r %%'
ax.clabel(CS, CS.ranges, inline=True, fmt=fmt, fontsize=10)
Kết quả :
<a checklist of seven textual content.Text objects>
Gắn nhãn các đường viền bằng các chuỗi thoải mái bằng việc dùng dictionary
fig1, ax1 = plt.subplots()
# Basic contour plot
CS1 = ax1.contour(X, Y, Z)
fmt = {}
strs = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh']
for l, s in zip(CS1.ranges, strs):
fmt[l] = s
# Label each different stage utilizing strings
ax1.clabel(CS1, CS1.ranges[::2], inline=True, fmt=fmt, fontsize=10)
Kết quả :
<a checklist of three textual content.Text objects>
Sử dụng Formatter :
fig2, ax2 = plt.subplots()
CS2 = ax2.contour(X, Y, 100**Z, locator=plt.LogLocator())
fmt = ticker.LogFormatterMathtext()
fmt.create_dummy_axis()
ax2.clabel(CS2, CS2.ranges, fmt=fmt)
ax2.set_title("$100^Z$")
plt.present()
Ví dụ 2 : Cách sử dụng phương thức axis.Axes.contourf () để tạo các đồ thị đường bao đã điền.
import numpy as np
import matplotlib.pyplot as plt
origin = 'decrease'
delta = 0.025
x = y = np.arange(-3.0, 3.01, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2
nr, nc = Z.form
# put NaNs in a single nook:
Z[-nr // 6:, -nc // 6:] = np.nan
# contourf will convert these to masked
Z = np.ma.array(Z)
Z[:nr // 6, :nc // 6] = np.ma.masked
# masks a circle within the center:
inside = np.sqrt(X**2 + Y**2) < 0.5
Z[interior] = np.ma.masked
# We are utilizing computerized number of contour ranges;
# that is often not such a good suggestion, as a result of they do not
# happen on good boundaries, however we do it right here for functions
# of illustration.
fig1, ax2 = plt.subplots(constrained_layout=True)
CS = ax2.contourf(X, Y, Z, 10, cmap=plt.cm.bone, origin=origin)
# Note that within the following, we explicitly go in a subset of
# the contour ranges used for the stuffed contours. Alternatively,
# We might go in further ranges to supply additional decision,
# or pass over the degrees kwarg to make use of all the unique ranges.
CS2 = ax2.contour(CS, ranges=CS.ranges[::2], colours='r', origin=origin)
ax2.set_title('Nonsense (3 masked areas)')
ax2.set_xlabel('phrase size anomaly')
ax2.set_ylabel('sentence size anomaly')
# Make a colorbar for the ContourSet returned by the contourf name.
cbar = fig1.colorbar(CS)
cbar.ax.set_ylabel('verbosity coefficient')
# Add the contour line ranges to the colorbar
cbar.add_lines(CS2)
fig2, ax2 = plt.subplots(constrained_layout=True)
# Now make a contour plot with the degrees specified,
# and with the colormap generated robotically from a listing
# of colours.
ranges = [-1.5, -1, -0.5, 0, 0.5, 1]
CS3 = ax2.contourf(X, Y, Z, ranges,
colours=('r', 'g', 'b'),
origin=origin,
lengthen='each')
# Our information vary extends exterior the vary of ranges; make
# information under the bottom contour stage yellow, and above the
# highest stage cyan:
CS3.cmap.set_under('yellow')
CS3.cmap.set_over('cyan')
CS4 = ax2.contour(X, Y, Z, ranges,
colours=('ok',),
linewidths=(3,),
origin=origin)
ax2.set_title('Listed colours (3 masked areas)')
ax2.clabel(CS4, fmt='%2.1f', colours='w', fontsize=14)
# Notice that the colorbar command will get all the knowledge it
# wants from the ContourSet object, CS3.
fig2.colorbar(CS3)
# Illustrate all 4 doable "lengthen" settings:
extends = ["neither", "both", "min", "max"]
cmap = plt.cm.get_cmap("winter")
cmap.set_under("magenta")
cmap.set_over("yellow")
# Note: contouring merely excludes masked or nan areas, so
# as an alternative of utilizing the "dangerous" colormap worth for them, it attracts
# nothing in any respect in them. Therefore the next would have
# no impact:
# cmap.set_bad("pink")
fig, axs = plt.subplots(2, 2, constrained_layout=True)
for ax, lengthen in zip(axs.ravel(), extends):
cs = ax.contourf(X, Y, Z, ranges, cmap=cmap, lengthen=lengthen, origin=origin)
fig.colorbar(cs, ax=ax, shrink=0.9)
ax.set_title("lengthen = %s" % lengthen)
ax.locator_params(nbins=4)
plt.present()