公眾號:Python程式設計時光
今天打算通過繪製正弦和餘弦函式,從預設的設定開始,一步一步地調整改進,讓它變得好看,變成我們初高中學習過的圖象那樣。通過這個過程來學習如何進行對圖表的一些元素的進行調整。
01. 簡單繪圖
matplotlib有一套允許定製各種屬性的預設設定。你可以幾乎控制matplotlib中的每一個預設屬性:影像大小,每英寸點數,線寬,色彩和樣式,子圖(axes),座標軸和網格屬性,文字和字型屬性,等等。
雖然matplotlib的預設設定在大多數情況下相當好,你卻可能想要在一些特別的情形下更改一些屬性。
from pylab import *
x = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(x), np.sin(x)
plot(x,C)
plot(x,S)
show()
複製程式碼
show image
02. 設定基本元素
這邊的基本元素主要有幾下幾點:
- 線的顏色,粗細,和線型
- 刻度和標籤
- 還有圖例
程式碼比較簡單,基本上在我的第一講內容裡都講過了。
import numpy as np
from matplotlib import pyplot as plt
plt.figure(figsize=(10,6), dpi=80)
x = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(x), np.sin(x)
# 設定線的顏色,粗細,和線型
plt.plot(x, C, color="blue", linewidth=2.5, linestyle="-", label=r`$sin(x)$`)
plt.plot(x, S, color="red", linewidth=2.5, linestyle="-", label=r`$cos(x)$`)
# 如果覺得線條離邊界太近了,可以加大距離
plt.xlim(x.min()*1.2, x.max()*1.2)
plt.ylim(C.min()*1.2, C.max()*1.2)
# 當前的刻度並不清晰,需要重新設定,並加上更直觀的標籤
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r`$-pi$`, r`$-pi/2$`, r`$0$`, r`$+pi/2$`, r`$+pi$`])
plt.yticks([-1,0,1],
[r`$-1$`, r`$0$`, r`$1$`])
# 新增圖例
plt.legend()
plt.show()
複製程式碼
show image
03. 移動軸線
還記得我們在初高中學習的三角函式圖象,可不是這樣,它應該是有四個象限的。而這裡卻是一個四四方方的圖表。
所以接下來,我們要做的就是移動軸線,讓它變成我們熟悉的樣子。
我們只需要兩軸線(x和y軸),所以我們需要將頂部和右邊的軸線給隱藏起來(顏色設定為None即可)。
# plt.gca(),全稱是get current axis
ax = plt.gca()
ax.spines[`right`].set_color(`none`)
ax.spines[`top`].set_color(`none`)
# 由於我們移動的是左邊和底部的軸,所以不用設定這兩個也可以
ax.xaxis.set_ticks_position(`bottom`)
ax.yaxis.set_ticks_position(`left`)
# 指定data型別,就是移動到指定數值
ax.spines[`bottom`].set_position((`data`,0))
ax.spines[`left`].set_position((`data`,0))
複製程式碼
關於set_position()
這個函式中的data是啥意思?我查了下官網。解釋如下
然後最後發現,上面的寫法可以用一定更簡潔的方式設定,是等價的。
ax.spines[`bottom`].set_position(`zero`)
ax.spines[`left`].set_position(`zero`)
複製程式碼
show image
04. 新增註釋
現在的圖形部分已經成型,接下讓我們現在使用annotate命令註解一些我們感興趣的點。
我們選擇2π/3
作為我們想要註解的正弦和餘弦值。我們將在曲線上做一個標記和一個垂直的虛線。然後,使用annotate命令來顯示一個箭頭和一些文字。
t = 2*np.pi/3
# 利用plt.plot繪製向下的一條垂直的線,利用plt.scatter繪製一個點。
plt.plot([t,t],[0,np.cos(t)], color =`blue`, linewidth=2.5, linestyle="--")
plt.scatter([t,],[np.cos(t),], 50, color =`blue`)
plt.annotate(r`$sin(frac{2pi}{3})=frac{sqrt{3}}{2}$`,
xy=(t, np.sin(t)), xycoords=`data`,
xytext=(+10, +30), textcoords=`offset points`, fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
# 利用plt.plot繪製向上的一條垂直的線,利用plt.scatter繪製一個點。
plt.plot([t,t],[0,np.sin(t)], color =`red`, linewidth=2.5, linestyle="--")
plt.scatter([t,],[np.sin(t),], 50, color =`red`)
plt.annotate(r`$cos(frac{2pi}{3})=-frac{1}{2}$`,
xy=(t, np.cos(t)), xycoords=`data`,
xytext=(-90, -50), textcoords=`offset points`, fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
複製程式碼
在這裡,你可能會對plt.annotate
這個函式的用法,有所陌生。這裡也解釋一下。
第一個引數,就是註釋內容;
第二個引數,xy
,就是對哪一點進行註釋;
第三個引數,xycoords
,指定型別,data 是說基於數值來定位;
第四個引數,xytext
,是註釋的位置,結合第五個引數,就是根據偏移量來決定註釋位置;
第五個引數,textcoords
,值為offset points,就是說是相對位置;
第六個引數,fontsize
,註釋大小;
第七個引數,arrowprops
,對箭頭的型別的一些設定。
show image
05. 完整程式碼
以上都是對片段程式碼進行解釋,這裡放出完整的程式碼
import numpy as np
from matplotlib import pyplot as plt
plt.figure(figsize=(10,6), dpi=80)
x = np.linspace(-np.pi, np.pi, 256,endpoint=True)
C,S = np.cos(x), np.sin(x)
# 設定線的顏色,粗細,和線型
plt.plot(x, C, color="blue", linewidth=2.5, linestyle="-", label=r`$sin(x)$`)
plt.plot(x, S, color="red", linewidth=2.5, linestyle="-", label=r`$cos(x)$`)
# 如果覺得線條離邊界太近了,可以加大距離
plt.xlim(x.min()*1.2, x.max()*1.2)
plt.ylim(C.min()*1.2, C.max()*1.2)
# 當前的刻度並不清晰,需要重新設定,並加上更直觀的標籤
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r`$-pi$`, r`$-pi/2$`, r`$0$`, r`$+pi/2$`, r`$+pi$`])
plt.yticks([-1,1],
[r`$-1$`, r`$1$`])
# 新增圖例
plt.legend(loc=`upper left`)
# plt.gca(),全稱是get current axis
ax = plt.gca()
ax.spines[`right`].set_color(`none`)
ax.spines[`top`].set_color(`none`)
# 由於我們移動的是左邊和底部的軸,所以不用設定這兩個也可以
ax.xaxis.set_ticks_position(`bottom`)
ax.yaxis.set_ticks_position(`left`)
# 指定data型別,就是移動到指定數值
# ax.spines[`bottom`].set_position(`zero`)
ax.spines[`bottom`].set_position((`data`,0))
ax.spines[`left`].set_position((`data`,0))
t = 2*np.pi/3
# 利用plt.plot繪製向下的一條垂直的線,利用plt.scatter繪製一個點。
plt.plot([t,t],[0,np.cos(t)], color =`blue`, linewidth=2.5, linestyle="--")
plt.scatter([t,],[np.cos(t),], 50, color =`blue`)
plt.annotate(r`$sin(frac{2pi}{3})=frac{sqrt{3}}{2}$`,
xy=(t, np.sin(t)), xycoords=`data`,
xytext=(+10, +30), textcoords=`offset points`, fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
# 利用plt.plot繪製向上的一條垂直的線,利用plt.scatter繪製一個點。
plt.plot([t,t],[0,np.sin(t)], color =`red`, linewidth=2.5, linestyle="--")
plt.scatter([t,],[np.sin(t),], 50, color =`red`)
plt.annotate(r`$cos(frac{2pi}{3})=-frac{1}{2}$`,
xy=(t, np.cos(t)), xycoords=`data`,
xytext=(-90, -50), textcoords=`offset points`, fontsize=16,
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.show()
複製程式碼