半小時拿下Python數據處理之Matplotlib篇


import numpy as np
import os
import matplotlib.pyplot as plt
#notebook模式下
%matplotlib inline

matplotlib三種代碼風格

pyplot

x=np.arange(0,10,1)
y=np.random.randn(len(x))
plt.plot(x,y) #繪製以x爲橫座標,y爲縱座標的折線圖
plt.title('pyplot')
plt.show()

pylab

#pylab不推薦使用
from pylab import *
x=arange(0,10,1)
y=randn(len(x))
plot(x,y) #繪製以x爲橫座標,y爲縱座標的折線圖
title('pylab')
show()

Object Oriented

在matplotlib中,整個圖像爲一個Figure對象。在Figure對象中可以包含一個,或者多個Axes對象。每個Axes對象都是一個擁有自己座標系統的繪圖區域。其邏輯關係如下:
整個圖像是fig對象。我們的繪圖中只有一個座標系區域,也就是ax。此外還有以下對象。

  • Data: 數據區,包括數據點、描繪形狀
  • Axis: 座標軸,包括 X 軸、 Y 軸及其標籤、刻度尺及其標籤
  • Title: 標題,數據圖的描述
  • Legend: 圖例,區分圖中包含的多種曲線或不同分類的數據
  • 其他的還有圖形文本 (Text)、註解 (Annotate)等其他描述

    Title爲標題。Axis爲座標軸,Label爲座標軸標註。Tick爲刻度線,Tick Label爲刻度註釋。各個對象之間有下面的對象隸屬關係:
# 推薦使用
x=np.arange(0,10,1)
y=np.random.randn(len(x))
fig=plt.figure() #定義圖像的對象
ax=fig.add_subplot(111) #定義座標系區域
ax.plot(x,y) #繪製以x爲橫座標,y爲縱座標的折線圖
ax.set_title('object oriented')
plt.show()

子圖

x = np.arange(1,100)

fig = plt.figure()
ax1 = fig.add_subplot(221) # 定義2*2個子圖(左一)
ax1.plot(x,x) # 繪製左一折線圖

ax2 = fig.add_subplot(222)
ax2.plot(x,-x) # 繪製右一折線圖(右一)

ax3 = fig.add_subplot(223)
ax3.plot(x,x*x) # 繪製左二折線圖(左二)

ax4 = fig.add_subplot(224)
ax4.plot(x,np.log(x)) # 繪製右二折線圖(右二)

plt.show()

x = np.arange(1,100)
plt.subplot(221) # 第一行的左圖
plt.plot(x,x)
plt.subplot(222) # 第一行的右圖
plt.plot(x,-x)
plt.subplot(212) # 第二整行
plt.plot(x,x*x)
plt.show()

#簡化寫法
fig,axes = plt.subplots(ncols=2,nrows=2) #定義子圖爲兩行兩列
ax1,ax2,ax3,ax4 = axes.ravel() #按照先行再列的順序分配子圖

x = np.arange(1,100)
ax1.plot(x,x)
ax2.plot(x,-x)
ax3.plot(x,x*x)
ax4.plot(x,np.log(x))
plt.show()

多圖

fig1 = plt.figure() # plt派生一個圖對象
ax1 = fig1.add_subplot(111)
ax1.plot([1,2,3],[3,2,1])

fig2 = plt.figure() # plt派生另一個圖對象
ax2 = fig2.add_subplot(111)
ax2.plot([1,2,3],[1,2,3])

plt.show() # plt統一顯示

散點圖(scatter)

fig,axes = plt.subplots(ncols=2,nrows=2)
ax1,ax2,ax3,ax4 = axes.ravel()
# example1
height=[161,170,182,175,173,165]
weight=[50,58,80,70,69,55]
ax1.scatter(height,weight) #繪製橫座標爲身高,縱座標爲體重散點圖

# example2
N = 1000
x = np.random.randn(N) #隨機生成一千個點
y = np.random.randn(N) #隨機生成一千個點
ax2.scatter(x,y) #繪製橫座標爲x,縱座標爲y散點圖

# example3

open,close=np.loadtxt('000001.csv',delimiter=',',skiprows=1,usecols=(1,4),unpack=True)
# loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0)
# fname:讀取文件的文件名。例如 '000001.csv'。
# dtype:數據類型。如float,str等。默認爲float
# comments 註釋
# delimiter:數據之間的分隔符。如使用逗號','。默認是空格
# skiprows跳過前幾行讀取,默認是0,必須是int整型。
# usecols:選取數據的列。
# unpack如果爲True,將分列讀取。

change=close-open
yesterday=change[:-1]
today=change[1:]
ax3.scatter(today,yesterday)

# example4
ax4.scatter(today,yesterday,s=50,c='r',marker='<',alpha=0.5)
# s:尺寸大小
# c: 顏色類型
# marker: 標記形狀
plt.show()

條形圖 (bar)

fig,axes = plt.subplots(ncols=2,nrows=2)
ax1,ax2,ax3,ax4 = axes.ravel()

N=5

y=[20,10,30,25,15]

index = np.arange(N)
# bar繪製條形圖
ax1.bar(left=index, height=y,width=0.3) #left:橫座標值 height:縱座標值 width:條形圖寬度
ax2.bar(left=index, height=y,color='red',width=0.3) # color:設置條形圖顏色
ax3.bar(left=0, bottom=index, width=y,height=0.5,orientation='horizontal')# orientation:'horizontal'設置爲橫向
ax4.barh(bottom=index,width=y,height=0.5) # barh 橫向條形圖
plt.show()

fig,axes = plt.subplots(ncols=2,nrows=2)
ax1,ax2,ax3,ax4 = axes.ravel()

index=np.arange(4)

sales_BJ=[52,55,63,53]
sales_SH=[44,66,55,41]
bar_width=0.3

ax1.bar(index,sales_BJ,bar_width,color='b')
ax1.bar(index+bar_width,sales_SH,bar_width,color='r') # index+bar_width實現橫向並排

ax2.bar(index,sales_BJ,bar_width,color='b')
ax2.bar(index,sales_SH,bar_width,color='r',bottom=sales_BJ) # bottom=sales_BJ實現縱向疊加

ax3.barh(bottom=index,width=sales_BJ,height=0.3,color='b')
ax3.barh(bottom=index+bar_width,width=sales_SH,height=0.3,color='r') # bottom=index+bar_width

ax4.barh(bottom=index,width=sales_BJ,height=0.3,color='b')
ax4.barh(bottom=index,width=sales_SH,height=0.3,color='r',left=sales_BJ) # left=sales_BJ

plt.show()

直方圖(hist)

fig = plt.figure()
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(212)

mu = 100
sigma = 20
x = mu +sigma * np.random.randn(2000)

ax1.hist(x,bins=10,color='green',normed=True) #輸入數據,bins=總共有幾條條狀圖,color=顏色,normed=True:縱座標總共爲1

ax2.hist(x,bins=50,color='red',normed=False) #normed=False:縱座標顯示實際值


x = np.random.randn(1000)+2
y = np.random.randn(1000)+3

ax3.hist2d(x,y,bins=10) #二維直方圖

plt.show()

餅狀圖(pie)

labels='frogs','hogs','dogs','logs'
sizes=15,20,45,10
colors='yellowgreen','gold','lightskyblue','lightcoral'
explode=0,0.1,0,0
plt.pie(sizes,explode=explode,labels=labels,colors=colors,labeldistance = 1.1 ,autopct='%3.1f%%',shadow=True,startangle=90,pctdistance = 0.6)
#labeldistance,文本的位置離遠點有多遠,1.1指1.1倍半徑的位置
#autopct,圓裏面的文本格式,%3.1f%%表示小數有三位,整數有一位的浮點數
#shadow,餅是否有陰影
#startangle,起始角度,0,表示從0開始逆時針轉,爲第一塊。一般選擇從90度開始比較好看
#pctdistance,百分比的text離圓心的距離
plt.axis('equal') #修正爲正圓 設置x,y軸刻度一致,這樣餅圖才能是圓的
plt.show()

箱型圖(boxplot)

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)

np.random.seed(100)

data = np.random.normal(size=1000, loc=0.0, scale=1.0)

ax1.boxplot(data,sym='o',whis=1.5)
# plt.boxplot(x, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, patch_artist=None, meanline=None, showmeans=None, showcaps=None, showbox=None, showfliers=None, boxprops=None, labels=None, flierprops=None, medianprops=None, meanprops=None, capprops=None, whiskerprops=None)
# x:指定要繪製箱線圖的數據;
# notch:是否是凹口的形式展現箱線圖,默認非凹口;
# sym:指定異常點的形狀,默認爲+號顯示;
# vert:是否需要將箱線圖垂直襬放,默認垂直襬放;
# whis:指定上下須與上下四分位的距離,默認爲1.5倍的四分位差;
# positions:指定箱線圖的位置,默認爲[0,1,2…];
# widths:指定箱線圖的寬度,默認爲0.5;
# patch_artist:是否填充箱體的顏色;
# meanline:是否用線的形式表示均值,默認用點來表示;
# showmeans:是否顯示均值,默認不顯示;
# showcaps:是否顯示箱線圖頂端和末端的兩條線,默認顯示;
# showbox:是否顯示箱線圖的箱體,默認顯示;
# showfliers:是否顯示異常值,默認顯示;
# boxprops:設置箱體的屬性,如邊框色,填充色等;
# labels:爲箱線圖添加標籤,類似於圖例的作用;
# filerprops:設置異常值的屬性,如異常點的形狀、大小、填充色等;
# medianprops:設置中位數的屬性,如線的類型、粗細等;
# meanprops:設置均值的屬性,如點的大小、顏色等;
# capprops:設置箱線圖頂端和末端線條的屬性,如顏色、粗細等;
# whiskerprops:設置須的屬性,如顏色、粗細、線的類型等;
data = np.random.normal(size=(100, 4), loc=0.0, scale=1.0)

labels = ['A','B','C','D']

ax2.boxplot(data, labels=labels)

plt.show()

顏色與樣式

顏色

樣式

  • 線條樣式

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-XuExvyUA-1589898432948)(http://image.yigouai.cn/2ddb1d67c59e9bedc5366fff124efdd8.png)]

  • 標記樣式

fig = plt.figure()
ax1 = fig.add_subplot(321)
ax2 = fig.add_subplot(322)
ax3 = fig.add_subplot(323)
ax4 = fig.add_subplot(324)
ax5 = fig.add_subplot(313)

#內建默認顏色
y=np.arange(1,5)
ax1.plot(y)


#灰色陰影,html,RGB
y=np.arange(1,5)
ax2.plot(y,'y')   #內建默認顏色
ax2.plot(y+1,color=(0.1,0.2,0.3)) #RGB
ax2.plot(y+2,'#FF00FF')  #html
ax2.plot(y+3,color='0.5') #灰色陰影


#線條樣式
y=np.arange(1,5)
ax3.plot(y,'--'); # 線條
ax3.plot(y+1,'-.'); # 點線
ax3.plot(y+2,':'); # 點

#點樣式,是否加線條取決於marker
y=np.arange(1,5)
ax4.plot(y,marker='o');
ax4.plot(y+1,marker='D');
ax4.plot(y+2,marker='^');
ax4.plot(y+3,'s');
ax4.plot(y+4,'p');
ax4.plot(y+5,'x');


#樣式字符串,同時表示顏色,點型,線性(重要!!)
y=np.arange(1,5)
ax5.plot(y,'cx--');
ax5.plot(y+1,'kp:');
ax5.plot(y+2,'mo-.');

plt.show()

網格(grid)

y = np.arange(1,5,0.1)
plt.plot(y,y**2)
plt.grid(True,color='r',linestyle='--',linewidth='2')
# True 顯示網格
# color 設置網格的顏色
# linestyle 設置線顯示的類型(一共四種)
# linewidth 設置網格的寬度
plt.show()

x= np.arange(1,10,0.1)
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.grid()
ax1.plot(x,np.log(x))
plt.show()

圖例(legend)

x = np.arange(1,11,1)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,x*2,label='Normal')
ax.plot(x,x*3,label='Fast')
ax.plot(x,x*4,label='Faster')
ax.plot(x,x*5,label='cool')
ax.plot(x,x*6,label='Best')
plt.legend(loc=0)
# loc= 0-10
# 0: ‘best'
# 1: ‘upper right'
# 2: ‘upper left'
# 3: ‘lower left'
# 4: ‘lower right'
# 5: ‘right'
# 6: ‘center left'
# 7: ‘center right'
# 8: ‘lower center'
# 9: ‘upper center'
# 10: ‘cente ’
# 參考 http://blog.csdn.net/helunqu2017/article/details/78641290
plt.show()

座標軸範圍調整

#ax.axis([0,10,0,100]) [x左,x右,y下,y上]
x = np.arange(-10,10,0.1)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,x**2)
ax.axis([0,10,0,100])

#plt.xlim([-5,5]) ,調整x軸座標範圍
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.plot(x,x**2)
plt.xlim([-5,5])
#相當於 plt.xlim(xmin=-5,xmax=5)

#plt.ylim([0,60]) ,調整y軸座標範圍
fig2 = plt.figure()
ax2 = fig2.add_subplot(111)
ax2.plot(x,x**2)
plt.ylim([0,60])
#相當於 plt.ylim(ymin=0,ymax=60)

plt.show()

座標軸刻度調整

x = np.arange(0,11,0.1)

fig1 = plt.figure()
ax1  = fig1.add_subplot(111)
ax1.plot(x,x)
#ax1.locator_params(nbins=20) #同時調整x軸與y軸
#ax1.locator_params('x',nbins=20) #只調整x軸
ax1.locator_params('y',nbins=20) #只調整y軸
plt.axis([0,10,0,10])


#日期的相關調整
start = datetime.datetime(2015,1,1)
stop  = datetime.datetime(2016,1,1)
delta = datetime.timedelta(days=1)

dates = mpl.dates.drange(start,stop,delta)
y = np.random.rand(len(dates))

fig2 = plt.figure()
ax2  = fig2.add_subplot(111)
ax2.plot_date(dates,y,linestyle='-',marker='')

#日期格式調整,不重疊
date_format= mpl.dates.DateFormatter('%Y-%m')
ax2.xaxis.set_major_formatter(date_format)
fig2.autofmt_xdate()#防止重疊

plt.show()

圖中添加新座標軸

x = np.arange(1,11,0.1)
y1 = x*x
y2 = np.log(x)

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax2 = ax1.twinx()

#ax1.set_ylable('Y1')
#ax2.set_ylable('Y2')

ax1.plot(x,y1)
ax2.plot(x,y2,'--r')

plt.show()

圖中畫註釋符號

x =np.arange(-10,11,1)
y = x*x

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.plot(x,y)
ax1.annotate('this is bottom',xy=(0,0),xytext=(-1.25,20),
             arrowprops=dict(facecolor='r',frac=0.2))
# annotate(s, xy, xytext=None, xycoords='data',textcoords='data'arrowprops=None, **kwargs)
# s : 描述的內容
# xy : 加描述的點
# xytext : 標註的位置,xytext=(30,-30),表示從標註點x軸方向上增加30,y軸方減30的位置
# xycoords 、textcoords :這兩個參數試了好多次沒弄明白,只知道 xycoords='dat給定就行,
# textcoords='offset points' 標註的內容從xy設置的點進行偏移xytext
# textcoords='data' 標註內容爲xytext的絕對座標
# fontsize : 字體大小,這個沒什麼好說的
# arrowstyle : 箭頭樣式'->'指向標註點 '<-'指向標註內容 還有很多'-'
               # '->'   head_length=0.4,head_width=0.2
               # '-['  widthB=1.0,lengthB=0.2,angleB=None
               # '|-|'     widthA=1.0,widthB=1.0
               # '-|>'  head_length=0.4,head_width=0.2
               # '<-'   head_length=0.4,head_width=0.2
               # '<->'   head_length=0.4,head_width=0.2
               # '<|-'  head_length=0.4,head_width=0.2
               # '<|-|>'     head_length=0.4,head_width=0.2
               # 'fancy'   head_length=0.4,head_width=0.4,tail_width=0.4
               # 'simple'  head_length=0.5,head_width=0.5,tail_width=0.2
               # 'wedge'   tail_width=0.3,shrink_factor=0.5
plt.show()

圖形中純文字標註

x =np.arange(-10,11,1)
y = x*x

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.plot(x,y)
ax1.text(-3,40,'function:y=x*x',family='fantasy',size=15,color='g',style='oblique',weight=20,bbox=dict(facecolor='r',alpha=0.2))
ax1.text(-3,30,'function:y=x*x',family='serif',size=15,color='r',style='italic',weight='black')

plt.show()

圖像中畫數學公式

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.set_xlim([1,7])
ax1.set_ylim([1,5])
ax1.text(2,4,r"$ \alpha_i \beta_j \pi \lambda \omega $",size=15)
ax1.text(4,4,r"$ \sin(0)=\cos(\frac{\pi}{2}) $",size=15)
ax1.text(2,2,r"$ \lim_{x \rightarrow y} \frac{1}{x^3} $",size=15)
ax1.text(4,2,r"$ \sqrt[4]{x}=\sqrt{y}$",size=15)
plt.show()

填充上色

x = np.linspace(0,5*np.pi,1000)
y1 = np.sin(x)
y2 = np.sin(2*x)

fig1 = plt.figure()
ax1 = fig1.add_subplot(111)

# ax1.fill(x,y1,'g',alpha=0.2)
# ax1.fill(x,y2,'r',alpha=0.2)
ax1.fill_between(x,y1,y2,where=y1>y2,facecolor='y')
ax1.fill_between(x,y1,y2,where=y1<y2,facecolor='b')
ax1.grid()

plt.show()

畫填充好的圖形

import matplotlib.patches as mpatches
fig,ax = plt.subplots()

xy1 = np.array([0.2,0.2])
xy2 = np.array([0.2,0.8])
xy3 = np.array([0.8,0.2])
xy4 = np.array([0.8,0.8])

circle = mpatches.Circle(xy1,0.05) #xy1 圓心
rect = mpatches.Rectangle(xy2,0.2,0.1,color='r') #xy2 左下角對應的點
polygen = mpatches.RegularPolygon(xy3,5,0.1,color='g') #xy3 圓心
ellipse = mpatches.Ellipse(xy4,0.4,0.2,color='y')

ax.add_patch(circle)
ax.add_patch(rect)
ax.add_patch(polygen)
ax.add_patch(ellipse)

plt.axis('equal')
plt.grid()
plt.show()

美化圖形

# 採用ggplot繪畫風格
plt.style.use('ggplot')

fig,axes = plt.subplots(ncols=2,nrows=2)
ax1,ax2,ax3,ax4 = axes.ravel()


x,y = np.random.normal(size=(2,100))
ax1.plot(x,y,'o')

x = np.arange(0,10)
y = np.arange(0,10)
ncolors = len(plt.rcParams['axes.color_cycle'])
shift = np.linspace(0,10,ncolors)
for s in shift:
    ax2.plot(x,y+s,'-')

x = np.arange(5)
y1,y2,y3 = np.random.randint(1,25,size=(3,5))
width = 0.25

ax3.bar(x,y1,width)
ax3.bar(x+width,y2,width,color='r')
ax3.bar(x+2*width,y3,width,color='g')

for i,color in  enumerate(plt.rcParams['axes.color_cycle']):
    xy = np.random.normal(size=2)
    ax4.add_patch(plt.Circle(xy,radius=0.3,color=color))
ax4.axis('equal')

plt.show()

極座標

plt.style.use('ggplot')

r = np.arange(1,6)
theta = [0,np.pi/2,np.pi,np.pi*3/2,2*np.pi]

ax = plt.subplot(111,projection='polar')

ax.plot(theta,r,color='r',linewidth=2)

ax.grid(True)

plt.show()

函數積分圖

def func(x):
    return -(x-2)*(x-8)+40

x = np.linspace(0,10)
y = func(x)

fig,axes = plt.subplots()
axes.plot(x,y,'r',linewidth=2)
a = 2
b = 9
axes.set_xticks([a,b])
axes.set_yticks([])
axes.set_xticklabels([r'$a$','$b$'])

ix = np.linspace(a,b)
iy = func(ix)
ixy = zip(ix,iy)

verts = [(a,0)]+list(ixy)+[(b,0)]
poly = Polygon(verts,facecolor='0.8',edgecolor='0.5')
axes.add_patch(poly)

plt.figtext(0.9,0.07,r'$x$')
plt.figtext(0.1,0.9,r'$y$')

x_math = (a+b)*0.5
y_math = 35

plt.text(x_math,y_math,r'$\int_a^b(-(x-2)*(x-8)+40)dx$',fontsize=10,horizontalalignment='center')

plt.show()

二維散點概率分佈圖

plt.style.use('ggplot')

x = np.random.randn(200)
y = x + np.random.randn(200)*0.5

margin_border = 0.1
width = 0.6
margin_between = 0.02
height = 0.2

left_s = margin_border
bottom_s = margin_border
height_s = width
width_s = width

left_x = margin_border
bottom_x = margin_border+width+margin_between
height_x = height
width_x = width

left_y = margin_border+width+margin_between
bottom_y = margin_border
height_y = width
width_y = height

plt.figure(1,figsize=(8,8))
rect_s = [left_s,bottom_s,width_s,height_s]
rect_x = [left_x,bottom_x,width_x,height_x]
rect_y = [left_y,bottom_y,width_y,height_y]

axScatter = plt.axes(rect_s)
axHisX = plt.axes(rect_x)
axHisY = plt.axes(rect_y)
axHisX.set_xticks([])
axHisY.set_yticks([])

axScatter.scatter(x,y)

bin_width = 0.25
xymax = np.max([np.max(np.fabs(x)),np.max(np.fabs(y))])

lim =int(xymax/bin_width+1) * bin_width

axScatter.set_xlim(-lim,lim)
axScatter.set_ylim(-lim,lim)

bins = np.arange(-lim,lim+bin_width,bin_width)

axHisX.hist(x,bins=bins)
axHisY.hist(y,bins=bins,orientation='horizontal')

axHisX.set_xlim(axScatter.get_xlim())
axHisY.set_ylim(axScatter.get_ylim())

plt.title('Scatter and Hist')
plt.show()

完整的繪製程序綜合

import numpy as np
import matplotlib.pyplot as plt
from pylab import *

# 定義數據部分
x = np.arange(0., 10, 0.2)
y1 = np.cos(x)
y2 = np.sin(x)
y3 = np.sqrt(x)

# 繪製 3 條函數曲線
plt.plot(x, y1, color='blue', linewidth=1.5, linestyle='-', marker='.', label=r'$y = cos{x}$')
plt.plot(x, y2, color='green', linewidth=1.5, linestyle='-', marker='*', label=r'$y = sin{x}$')
plt.plot(x, y3, color='m', linewidth=1.5, linestyle='-', marker='x', label=r'$y = \sqrt{x}$')

# 座標軸上移
ax = plt.subplot(111)
ax.spines['right'].set_color('none')     # 去掉右邊的邊框線
ax.spines['top'].set_color('none')       # 去掉上邊的邊框線

# 移動下邊邊框線,相當於移動 X 軸
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))

# 移動左邊邊框線,相當於移動 y 軸
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))

# 設置 x, y 軸的取值範圍
plt.xlim(x.min()*1.1, x.max()*1.1)
plt.ylim(-1.5, 4.0)

# 設置 x, y 軸的刻度值
plt.xticks([2, 4, 6, 8, 10], [r'2', r'4', r'6', r'8', r'10'])
plt.yticks([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0],
    [r'-1.0', r'0.0', r'1.0', r'2.0', r'3.0', r'4.0'])

# 添加文字
plt.text(4, 1.68, r'$x \in [0.0, \ 10.0]$', color='k', fontsize=15)
plt.text(4, 1.38, r'$y \in [-1.0, \ 4.0]$', color='k', fontsize=15)

# 特殊點添加註解
plt.scatter([8,],[np.sqrt(8),], 50, color ='m')  # 使用散點圖放大當前點
plt.annotate(r'$2\sqrt{2}$', xy=(8, np.sqrt(8)), xytext=(8.5, 2.2), fontsize=16, color='#090909', arrowprops=dict(arrowstyle='->', connectionstyle='arc3, rad=0.1', color='#090909'))

# 設置標題、x軸、y軸
plt.title(r'$the \ function \ figure \ of \ cos(), \ sin() \ and \ sqrt()$', fontsize=19)
plt.xlabel(r'$the \ input \ value \ of \ x$', fontsize=18, labelpad=88.8)
plt.ylabel(r'$y = f(x)$', fontsize=18, labelpad=12.5)

# 設置圖例及位置
plt.legend(loc='up right')
# plt.legend(['cos(x)', 'sin(x)', 'sqrt(x)'], loc='up right')

# 顯示網格線
plt.grid(True)

# 顯示繪圖
plt.show()

繪製三維圖形

首先補充一下numpymeshgrid函數的用法。具體含義如下圖所示
函數的用法

繪製3D曲面圖

from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D #導入三維繪製工具箱

fig = plt.figure() # 創建一個繪圖對象
ax = Axes3D(fig) # #用這個繪圖對象創建一個Axes對象(有3D座標)
X = np.arange(-4, 4, 0.25) #創建從-4到4,步長爲0.25的arange對象
Y = np.arange(-4, 4, 0.25)
X, Y = np.meshgrid(X, Y) #用這兩個arange對象中的可能取值一一映射去擴充爲所有可能的取樣點
R = np.sqrt(X**2 + Y**2) #函數表示
Z = np.sin(R)
# 具體函數方法可用 help(function) 查看,如:help(ax.plot_surface)
# rstride和cstride表示行列隔多少個取樣點建一個小面
# cmap表示繪製曲面的顏色
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='rainbow')

plt.show()

繪製三維散點圖

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

data = np.random.randint(0, 255, size=[40, 40, 40])
#data = np.random.randint(0, 255, size=[3,40, 40, 40]) #四維
x, y, z = data[0], data[1], data[2]
#x, y, z = data[0,1], data[0,2], data[0,3] #取值時需要[0,index]
ax = plt.subplot(111, projection='3d')  # 創建一個三維的繪圖工程
#  將數據點分成三部分畫,在顏色上有區分度
ax.scatter(x[:10], y[:10], z[:10], c='y')  # 繪製數據點
ax.scatter(x[10:20], y[10:20], z[10:20], c='r')
ax.scatter(x[30:40], y[30:40], z[30:40], c='g')

ax.set_zlabel('Z')  # 座標軸
ax.set_ylabel('Y')
ax.set_xlabel('X')
plt.show()

保存圖像爲矢量圖

用python的matplotlib畫出的圖,一般是需要保存到本地使用的。如果是用show()展出的圖,再右鍵保存,這樣的圖是失幀而非矢量的。
保存矢量圖的方法是使用函數savefig(),接口定義如下:


savefig(fname, dpi=None, facecolor='w', edgecolor='w',
        orientation='portrait', papertype=None, format=None,
        transparent=False, bbox_inches=None, pad_inches=0.1,
        frameon=None, metadata=None)

可以看到它的參數還是很多的,但保存矢量圖只需要用到三個參數,即

  • fname: 文件名稱,
  • dpi: 每英寸點的分辨率。根據Wiley的關於圖像的指導準則,一般折線圖的dpi設置爲600,而圖像的dpi設置爲300。
  • format: 文件格式。支持的格式包括:.eps, .jpeg, .jpg, .pdf, .pgf, .png, .ps, .raw, .rgba, .svg, .svgz, .tif, .tiff。

一個完整的保存矢量圖的代碼爲:


import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x1 = np.random.uniform(-10, 10, size=20)
x2 = np.random.uniform(-10, 10, size=20)

number = []
x11 = []
x12 = []
for i in range(20):
    number.append(i+1)
    x11.append(i+1)
    x12.append(i+1)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(number, x1, 'bo', markersize=20,label='a')  # blue circle with size 20
plt.plot(number, x2, 'ro', ms=10,label='b')  # ms is just an alias for markersize
 
lgnd=plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0,numpoints=1,fontsize=10)
lgnd.legendHandles[0]._legmarker.set_markersize(16)
lgnd.legendHandles[1]._legmarker.set_markersize(10)
 
plt.show()
 
fig.savefig('scatter.eps',dpi=600,format='eps')

保存矢量圖的具體代碼爲最後一行 ,此處保存的名稱爲scatter,格式爲eps,分辨率爲600。

繪製函數圖顯示並保存爲矢量圖



import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()

def f(x,eta):
    mask = x < 0.5
    y = (np.power(2.0*x,1.0/(eta+1))-1.0)*mask + (1.0 - np.power(2.0*(1-x),1.0/(1+eta)))*(1-mask)
    return y

x = np.linspace(0.01, 0.99, 100)

y1 = f(x,1)
y2 = f(x,2)
y3 = f(x,4)
y4 = f(x,8)
 
plt.plot(x, y1,label=r'$\eta=1$')
plt.plot(x, y2,label=r'$\eta=2$')
plt.plot(x, y3,label=r'$\eta=4$')
plt.plot(x, y4,label=r'$\eta=8$')

 
# plt.title('line chart')
plt.xlabel(r'$\mu$')
plt.ylabel(r'$\beta$')

plt.legend(loc=0)

plt.show()

fig.savefig('mutation.pdf',dpi=600,format='pdf')


參考

matplotlib核心剖析

Numpy中Meshgrid函數介紹及2種應用場景


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章