Python繪製正餘弦函式影像

Python程式設計時光發表於2019-03-02

公眾號: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

Python繪製正餘弦函式影像

02. 設定基本元素

這邊的基本元素主要有幾下幾點:

  1. 線的顏色,粗細,和線型
  2. 刻度和標籤
  3. 還有圖例

程式碼比較簡單,基本上在我的第一講內容裡都講過了。

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

Python繪製正餘弦函式影像

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是啥意思?我查了下官網。解釋如下

Python繪製正餘弦函式影像

然後最後發現,上面的寫法可以用一定更簡潔的方式設定,是等價的。

ax.spines[`bottom`].set_position(`zero`)
ax.spines[`left`].set_position(`zero`)
複製程式碼

show image

Python繪製正餘弦函式影像

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

Python繪製正餘弦函式影像

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()
複製程式碼

Python繪製正餘弦函式影像

相關文章