字体设置¶
In [1]:
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
# plt.rcParams['font.sans-serif'] = ['KaiTi', 'SimHei', 'FangSong']
mpl.rcParams['axes.unicode_minus'] = False
基础知识¶
图形绘制¶
In [2]:
import numpy as np
import matplotlib.pyplot as plt # 画图的画笔
x = np.linspace(0,2*np.pi,100)
y = np.sin(x)
plt.plot(x,y)
plt.grid(linestyle = '--', # 网格线样式
color = 'green', # 颜色
alpha = 0.75) # 透明度,网格线
plt.xlim([-1,10]) # 横坐标范围
plt.ylim([-1.5,1.5]) # 纵坐标范围
Out[2]:
(-1.5, 1.5)
坐标轴刻度,标签,标题¶
$\frac{\pi}{2}$
In [3]:
plt.figure(figsize=(9,6))
plt.plot(x,y)
plt.yticks([-1,0,1],['min',0,'max'],fontsize = 18)
plt.ylabel('y = sin(x)',rotation = 0,fontsize = 18,ha = 'right')
_ = plt.xticks([0,np.pi/2,np.pi,3*np.pi/2,2*np.pi],
[0,'$\\frac{\pi}{2}$',r'$\pi$',r'$\frac{3\pi}{2}$',r'$2\pi$'],
fontsize = 18,
color = 'red')
plt.title('正弦波',fontsize = 18,color = 'red',family = 'Heiti TC')
Out[3]:
Text(0.5, 1.0, '正弦波')
In [4]:
# 电脑上字体
from matplotlib.font_manager import FontManager
fm = FontManager()
In [5]:
[font.name for font in fm.ttflist]
Out[5]:
['cmr10', 'STIXSizeOneSym', 'DejaVu Sans Mono', 'STIXNonUnicode', 'STIXSizeTwoSym', 'STIXGeneral', 'DejaVu Sans Mono', 'STIXSizeThreeSym', 'SimHei', 'cmsy10', 'DejaVu Sans Mono', 'STIXSizeOneSym', 'cmmi10', 'cmtt10', 'DejaVu Serif', 'STIXNonUnicode', 'DejaVu Sans', 'STSong', 'DejaVu Sans Mono', 'DejaVu Serif', 'STIXSizeTwoSym', 'STIXGeneral', 'STIXNonUnicode', 'DejaVu Serif', 'STIXGeneral', 'DejaVu Sans', 'cmex10', 'cmb10', 'STIXNonUnicode', 'STIXSizeFourSym', 'DejaVu Sans', 'DejaVu Sans', 'DejaVu Serif Display', 'STIXGeneral', 'DejaVu Sans Display', 'STIXSizeFourSym', 'STIXSizeThreeSym', 'cmss10', 'DejaVu Serif', 'STIXSizeFiveSym', 'Nimbus Roman', 'P052', 'Nimbus Roman', 'Nimbus Sans', 'DejaVu Sans', 'URW Gothic', 'Cantarell', 'Nimbus Sans Narrow', 'URW Bookman', 'Cantarell', 'DejaVu Sans', 'D050000L', 'DejaVu Sans', 'DejaVu Sans', 'Nimbus Sans', 'C059', 'Nimbus Mono PS', 'Cantarell', 'Nimbus Roman', 'Nimbus Roman', 'URW Bookman', 'Nimbus Sans Narrow', 'P052', 'Nimbus Sans Narrow', 'URW Bookman', 'Nimbus Mono PS', 'C059', 'Nimbus Sans', 'DejaVu Sans', 'DejaVu Sans', 'DejaVu Sans', 'C059', 'P052', 'Nimbus Mono PS', 'Nimbus Sans Narrow', 'URW Gothic', 'DejaVu Sans', 'C059', 'Heiti TC', 'Nimbus Sans', 'P052', 'URW Bookman', 'Cantarell', 'SimHei', 'URW Gothic', 'URW Gothic', 'Z003', 'Nimbus Mono PS', 'DejaVu Sans']
图例¶
In [6]:
x = np.arange(0,2*np.pi,step = np.pi/50) # 100份数据
plt.figure(figsize=(9,6))
plt.plot(x,np.sin(x))
plt.plot(x,np.cos(x))
# 这里宽度高度都是相对的
x = 0 # 图片宽度
y = 1.05 # 图片的高度
width = 1
height = 0.2
plt.legend(['Sin','Cos'],fontsize = 18,loc = 'center',ncol = 2,
bbox_to_anchor = (x,y,width,height))# 指定图例相对位置
Out[6]:
<matplotlib.legend.Legend at 0x7f7380ab9280>
脊柱移动¶
In [7]:
x = np.linspace(-np.pi,np.pi,100)
plt.figure(figsize=(9,6))
plt.plot(x,np.sin(x),x,np.cos(x))
axes = plt.gca() # get current axes 轴面,子视图
axes.spines['top'].set_color('white')
axes.spines['right'].set_color('white')
axes.spines['left'].set_position(('data',0)) # data 表示数据,表示数值
axes.spines['bottom'].set_position(('data',0))
plt.yticks([-1,0,1])
_ = plt.xticks([-np.pi,-np.pi/2,0,np.pi/2,np.pi],
[r'$-\pi$',r'$-\frac{\pi}{2}$','0',r'$\frac{\pi}{2}$',r'$\pi$'],
fontsize = 18,
color = 'red')
图片保存¶
In [8]:
plt.figure(figsize=(9,6),linewidth = 5) # 创建了一个figure 图片
plt.plot(x,np.sin(x),x,np.cos(x)) # 在轴面中,进行图片的绘制
plt.legend(['Sin','Cos'],loc = 'center',ncol = 2,bbox_to_anchor = (0,1.05,1,0.2),fontsize = 18)
axes = plt.gca()
axes.set_facecolor('lightgreen') # 轴面,被figure(图片)包围着
plt.savefig('./image.png',
dpi = 100,
facecolor = 'red', # 大图片和轴面(子视图间隔的颜色)
edgecolor = 'lightgreen', # 边界的颜色
bbox_inches = 'tight') # 设置紧凑显示,保存整张图片
风格和样式¶
颜色、线宽、线型、透明度、点型¶
In [9]:
x = np.linspace(0,2*np.pi,20)
y1 = np.sin(x)
y2 = np.cos(x)
plt.plot(x,y1,color = 'red',linestyle = '--',alpha = 0.5,marker = 'o')
plt.plot(x,y2,color = 'k',linestyle = '-.',marker = '*')
plt.plot(x,y1 + y2,color = 'indigo',linestyle = ':',marker = 'd')
plt.plot(x,y1 - 2*y2,color = '#FF00FF',linestyle = '--',marker = '1')
plt.plot(x,2*y1 + y2,
color = (0.2,0.6,0.5), # 红绿蓝,三原色
ls = '-.',marker = '3',markersize = 20,linewidth = 5)
Out[9]:
[<matplotlib.lines.Line2D at 0x7f737ff493d0>]
更多设置¶
In [10]:
x = np.linspace(0,5,50)
def fun(x):
return np.exp(-x)*np.cos(2*np.pi*x)
y = fun(x)
plt.figure(figsize=(9,6))
plt.plot(x,y,marker = 'o',
color = 'green',
markersize = 12,
markerfacecolor = 'red',
linestyle = '--',
markeredgecolor = 'blue',
markeredgewidth = 3,
alpha = 0.7)
Out[10]:
[<matplotlib.lines.Line2D at 0x7f7380da4ac0>]
多图布局¶
子视图¶
In [11]:
plt.figure(figsize=(9,6))
x = np.linspace(0,2*np.pi,20)
y = np.sin(x)
axes = plt.subplot(2,2,1) # 子视图,轴面,左上角位置
axes.set_facecolor('green')
axes.plot(x,y,color = 'red')
axes = plt.subplot(222) # 连起来写,右上角,轴面,X轴Y轴
line, = axes.plot(x,y) # 调用plot返回绘制对象,一条线
line.set_color('green')
line.set_linestyle('--')
line.set_marker('o')
axes = plt.subplot(2,1,2) # 2行,一列第二个,就是已经画好的子视图下面的区域
x = np.linspace(-np.pi,np.pi,200)
y = np.sin(x*x)
# axes.plot(x,y)
plt.plot(x,y) # 默认持有最近的这个子视图,索引调用plot方法,绘制图形就是像最近这个轴面绘制
Out[11]:
[<matplotlib.lines.Line2D at 0x7f7380ca93d0>]
嵌套¶
In [12]:
fig = plt.figure(figsize=(9,6)) # fig就是整张图片
x = np.linspace(0,2*np.pi,100)
y = np.sin(x)
plt.plot(x,y)
# left,bottom坐标位置,范围0 ~ 1 0表示左下角,1 表示右上角
# width 宽度
# height 高度
ax = plt.axes([0.6,0.6,0.2,0.2]) # 轴面 [left, bottom, width, height]
ax.plot(x,y,color = 'red')
ax = fig.add_axes([0.2,0.2,0.2,0.2])
ax.plot(x,y,color = 'green',ls = '--')
Out[12]:
[<matplotlib.lines.Line2D at 0x7f737ee7afd0>]
多图布局分格显示¶
均匀布局¶
In [13]:
### x = np.linspace(0,2*np.pi,200)
fig,((ax11,ax12,ax13),(ax21,ax22,ax23),(ax31,ax32,ax33)) = plt.subplots(3,3) # 返回子视图
fig.set_figwidth(12)
fig.set_figheight(9)
ax11.plot(x,np.sin(x))
ax12.plot(x,np.cos(x))
ax13.plot(x,np.tan(x))
ax21.plot(x,np.tanh(x))
ax22.plot(x,np.sin(x*x))
ax23.plot(x,np.cos(x*x))
ax31.plot(x,np.sin(x)*np.cos(x))
ax32.plot(x,np.sin(x) + np.cos(x))
ax33.plot(x,np.sin(2*np.pi*x)*np.exp(-x))
plt.tight_layout() # 紧凑布局
不均匀布局¶
In [14]:
from matplotlib import gridspec
In [15]:
plt.figure(figsize=(12,9))
x = np.linspace(0,2*np.pi,200)
gs = gridspec.GridSpec(3,3) # 3行3列
ax = plt.subplot(gs[0,:]) # :默认情况,占满,3列
ax.plot(x,np.sin(10*x))
ax = plt.subplot(gs[1,:2])
ax.set_facecolor('green')
ax.plot(x,np.cos(x),color = 'red')
ax = plt.subplot(gs[1:,2])
ax.plot(x,np.sin(x))
ax = plt.subplot(gs[2,0])
ax.plot(x,np.cos(2*np.pi*x)*np.exp(-x))
ax = plt.subplot(gs[2,1])
ax.plot([0,1,2],[0,1,2],marker = 'o')
Out[15]:
[<matplotlib.lines.Line2D at 0x7f737eae7ca0>]
双轴显示¶
In [16]:
x = np.linspace(-np.pi,np.pi,200)
y1 = np.sin(x)
y2 = np.exp(x)
plt.figure(figsize=(9,6))
ax1 = plt.subplot(111)
ax1.plot(x,y1,color = 'red')
plt.yticks(color = 'red',fontsize = 18)
plt.ylabel('Sin',fontsize=18,color = 'red')
# 两个子视图公用一个X轴,两个Y轴
ax2 = ax1.twinx() # !!! 双x轴,共享X轴,返回一个新的子视图;twiny
ax2.plot(x,y2,color = 'blue')
plt.yticks(color = 'blue',fontsize = 18)
plt.ylabel('Exp',color = 'blue',fontsize = 18)
Out[16]:
Text(0, 0.5, 'Exp')
文本、注释、箭头¶
文本¶
In [17]:
plt.figure(figsize=(9,6))
x = np.linspace(0,2*np.pi,200)
y = np.cos(2*np.pi*x)*np.exp(-x)
plt.plot(x,y)
plt.text(x = 3,y = 0.4,s = r'$exp(-x)*sin(2\pi x)$',fontsize = 18,color = 'red')
plt.xlabel('X',fontsize = 18)
plt.ylabel('Y',fontsize = 18)
plt.title('Exp decay',fontdict = {'color':'red','fontsize':'18','alpha':0.4,'rotation':30})
plt.suptitle('指数衰减',fontfamily = 'SimHei',fontsize = 18)
Out[17]:
Text(0.5, 0.98, '指数衰减')
In [18]:
from matplotlib.font_manager import FontManager
In [19]:
fm = FontManager()
In [20]:
[font.name for font in fm.ttflist]
Out[20]:
['cmr10', 'STIXSizeOneSym', 'DejaVu Sans Mono', 'STIXNonUnicode', 'STIXSizeTwoSym', 'STIXGeneral', 'DejaVu Sans Mono', 'STIXSizeThreeSym', 'SimHei', 'cmsy10', 'DejaVu Sans Mono', 'STIXSizeOneSym', 'cmmi10', 'cmtt10', 'DejaVu Serif', 'STIXNonUnicode', 'DejaVu Sans', 'STSong', 'DejaVu Sans Mono', 'DejaVu Serif', 'STIXSizeTwoSym', 'STIXGeneral', 'STIXNonUnicode', 'DejaVu Serif', 'STIXGeneral', 'DejaVu Sans', 'cmex10', 'cmb10', 'STIXNonUnicode', 'STIXSizeFourSym', 'DejaVu Sans', 'DejaVu Sans', 'DejaVu Serif Display', 'STIXGeneral', 'DejaVu Sans Display', 'STIXSizeFourSym', 'STIXSizeThreeSym', 'cmss10', 'DejaVu Serif', 'STIXSizeFiveSym', 'Nimbus Roman', 'P052', 'Nimbus Roman', 'Nimbus Sans', 'DejaVu Sans', 'URW Gothic', 'Cantarell', 'Nimbus Sans Narrow', 'URW Bookman', 'Cantarell', 'DejaVu Sans', 'D050000L', 'DejaVu Sans', 'DejaVu Sans', 'Nimbus Sans', 'C059', 'Nimbus Mono PS', 'Cantarell', 'Nimbus Roman', 'Nimbus Roman', 'URW Bookman', 'Nimbus Sans Narrow', 'P052', 'Nimbus Sans Narrow', 'URW Bookman', 'Nimbus Mono PS', 'C059', 'Nimbus Sans', 'DejaVu Sans', 'DejaVu Sans', 'DejaVu Sans', 'C059', 'P052', 'Nimbus Mono PS', 'Nimbus Sans Narrow', 'URW Gothic', 'DejaVu Sans', 'C059', 'Heiti TC', 'Nimbus Sans', 'P052', 'URW Bookman', 'Cantarell', 'SimHei', 'URW Gothic', 'URW Gothic', 'Z003', 'Nimbus Mono PS', 'DejaVu Sans']
箭头¶
In [21]:
plt.figure(figsize=(9,6))
data = np.random.randint(0,10,size = (10,2))
plt.scatter(x = data[:,0],y = data[:,1],color = 'green',marker = '*',s = 100)
for i in range(9):
start = data[i] # 起始
end = data[i + 1] # 终点
plt.arrow(x = start[0],y = start[1], # 起点坐标
dx = end[0] - start[0],dy = end[1] - start[1],#水平和竖直举例
lw = 2,# 线宽
head_width = 0.2,# 箭头宽度
length_includes_head = True)# 长度计算包含箭头长度)
plt.text(start[0],start[1],i,fontsize = 18,color = 'red')
if i == 8:
plt.text(end[0],end[1],i + 1,fontsize = 18,color = 'red')
注释¶
In [22]:
plt.figure(figsize=(9,6))
x = np.linspace(0,20,300)
plt.plot(x,np.sin(x))
plt.ylim([-2,2])
plt.annotate('max', # 文本
xy=(np.pi/2,1), # 指向位置的坐标点
xytext =(3,1.5), # 文本位置
arrowprops = {'width':2,'headwidth':6,'headlength':15,'shrink':0})
plt.annotate('median',
xy = (2*np.pi,0),
xytext = (1.25,-0.65),
arrowprops = {'arrowstyle':'fancy'})
plt.annotate('min',
xy = (3.5*np.pi,-1),
xytext = (15.5,-1.65),
arrowprops = {'arrowstyle':'-|>',
# 水平向右是0度,竖直向上90,水平向左是180,竖直向下270,-90
# 'connectionstyle':'angle,angleA=90,angleB=180,rad=10',
# 'connectionstyle':'angle3,angleA=60, angleB=0',
'connectionstyle':'arc,angleA=90, angleB=0, armA=30, armB=60, rad=10'})
Out[22]:
Text(15.5, -1.65, 'min')
常用图表¶
折线图¶
In [23]:
plt.figure(figsize=(9,6))
y = np.random.randint(0,10,15)
plt.plot(y,marker = '*') # 只给了一个参数,Y轴,X轴默认:从0~N
plt.plot(y.cumsum(),marker = 'o')
# 多图布局
fig,axes = plt.subplots(2,1)
fig.set_figwidth(9)
fig.set_figheight(6)
axes[0].plot(y,marker = '*')
axes[1].plot(y.cumsum(),marker = 'o')
Out[23]:
[<matplotlib.lines.Line2D at 0x7f737d8e1d00>]
条形图、柱状图¶
In [24]:
y1 = np.random.randint(20,35,6) # 男
y2 = np.random.randint(20,35,6) # 女
plt.figure(figsize=(9,6))
x = np.array(['G1','G2','G3','G4','G5','G6'])
plt.bar(x,y1,color = 'orange',width = 0.5,yerr = 4,ecolor = 'red',capsize = 5)
plt.bar(x,y2,bottom = y1,width = 0.5,yerr = 2,ecolor = 'red',capsize = 5) # y2画到y1上面
plt.legend(['Men','Women'])
Out[24]:
<matplotlib.legend.Legend at 0x7f737d831e50>
分组带标签
In [25]:
x = np.arange(6)
labels = np.array(['G1','G2','G3','G4','G5','G6'])
width = 0.4
plt.figure(figsize=(12,9))
bars = plt.bar(x - width/2,y1,width = width)
for i,bar in enumerate(bars):
h = bar.get_height()
w = bar.get_width()
plt.text(x = bar.get_x() + w/2 ,
y = h + 0.5,s = y1[i],ha = 'center')
bars = plt.bar(x + width/2,y2,width = width)
for i,bar in enumerate(bars):
h = bar.get_height()
w = bar.get_width()
plt.text(x = bar.get_x() + w/2 ,
y = h + 0.5,s = y2[i],ha = 'center')
plt.legend(['Men','Women'])
Out[25]:
<matplotlib.legend.Legend at 0x7f737e9c0f70>
极坐标图¶
In [26]:
x = np.linspace(0,4*np.pi,300) # 弧度制
y = np.linspace(0,3,300)
ax = plt.subplot(111,projection = 'polar',facecolor = 'lightgreen') # 极坐标
ax.plot(x,y,color = 'red') # 折线图,
ax.set_rmax(4) # 高度,半径
ax.set_rticks([0,1.5,3])
ax.set_rlabel_position(-45)
In [27]:
x = np.arange(0,2*np.pi,step = np.pi/4) # 弧度值
y = np.random.randint(1,10,size = 8)
plt.figure(figsize=(8,8))
ax = plt.subplot(111,polar = True,facecolor = 'lightgreen')
ax.bar(x,y,width = np.pi/4,color = np.random.rand(8,3))
Out[27]:
<BarContainer object of 8 artists>
直方图¶
In [28]:
# 数据分布情况
x = np.random.randn(10000) # 正态分布
# count是统计次数;bins范围
count,bins, fig= plt.hist(x,bins = 100,color = 'red',density=True)# 其实就是条形图
In [29]:
display(count,bins)
array([0.00136451, 0. , 0. , 0.00136451, 0.00272902,
0.00136451, 0.00136451, 0.00136451, 0.00272902, 0.00136451,
0.00545804, 0.00545804, 0.00409353, 0.00545804, 0.00955157,
0. , 0.00955157, 0.0136451 , 0.02046765, 0.03138374,
0.02592569, 0.03001923, 0.02865472, 0.03411276, 0.04775786,
0.04639335, 0.06276747, 0.05867394, 0.07777708, 0.08596415,
0.10779631, 0.12689945, 0.13645102, 0.15146064, 0.13235749,
0.17875084, 0.21013458, 0.2265087 , 0.23333125, 0.20740556,
0.21968615, 0.30837931, 0.29473421, 0.32611795, 0.33566952,
0.33430501, 0.34522109, 0.34931462, 0.37796934, 0.39024993,
0.38069836, 0.41071758, 0.39024993, 0.36568875, 0.39161444,
0.40116601, 0.38752091, 0.39024993, 0.39024993, 0.35886619,
0.37933385, 0.29200519, 0.30837931, 0.26471499, 0.2933697 ,
0.27153754, 0.25925695, 0.24151831, 0.23060223, 0.21149909,
0.15555417, 0.15555417, 0.14463809, 0.09688023, 0.11325435,
0.10916082, 0.08187061, 0.07914159, 0.07777708, 0.07231904,
0.05048688, 0.05458041, 0.02865472, 0.04093531, 0.03547727,
0.02456118, 0.02456118, 0.01091608, 0.00955157, 0.00682255,
0.01228059, 0.00682255, 0.00545804, 0.00682255, 0.00136451,
0. , 0.00682255, 0. , 0.00136451, 0.00272902])
array([-3.87851826, -3.8052319 , -3.73194553, -3.65865916, -3.58537279,
-3.51208642, -3.43880005, -3.36551369, -3.29222732, -3.21894095,
-3.14565458, -3.07236821, -2.99908185, -2.92579548, -2.85250911,
-2.77922274, -2.70593637, -2.63265001, -2.55936364, -2.48607727,
-2.4127909 , -2.33950453, -2.26621816, -2.1929318 , -2.11964543,
-2.04635906, -1.97307269, -1.89978632, -1.82649996, -1.75321359,
-1.67992722, -1.60664085, -1.53335448, -1.46006812, -1.38678175,
-1.31349538, -1.24020901, -1.16692264, -1.09363627, -1.02034991,
-0.94706354, -0.87377717, -0.8004908 , -0.72720443, -0.65391807,
-0.5806317 , -0.50734533, -0.43405896, -0.36077259, -0.28748623,
-0.21419986, -0.14091349, -0.06762712, 0.00565925, 0.07894562,
0.15223198, 0.22551835, 0.29880472, 0.37209109, 0.44537746,
0.51866382, 0.59195019, 0.66523656, 0.73852293, 0.8118093 ,
0.88509566, 0.95838203, 1.0316684 , 1.10495477, 1.17824114,
1.25152751, 1.32481387, 1.39810024, 1.47138661, 1.54467298,
1.61795935, 1.69124571, 1.76453208, 1.83781845, 1.91110482,
1.98439119, 2.05767755, 2.13096392, 2.20425029, 2.27753666,
2.35082303, 2.4241094 , 2.49739576, 2.57068213, 2.6439685 ,
2.71725487, 2.79054124, 2.8638276 , 2.93711397, 3.01040034,
3.08368671, 3.15697308, 3.23025944, 3.30354581, 3.37683218,
3.45011855])
In [30]:
np.histogram(x,bins = 100) # NumPy提供了方法,统计计数
Out[30]:
(array([ 1, 0, 0, 1, 2, 1, 1, 1, 2, 1, 4, 4, 3,
4, 7, 0, 7, 10, 15, 23, 19, 22, 21, 25, 35, 34,
46, 43, 57, 63, 79, 93, 100, 111, 97, 131, 154, 166, 171,
152, 161, 226, 216, 239, 246, 245, 253, 256, 277, 286, 279, 301,
286, 268, 287, 294, 284, 286, 286, 263, 278, 214, 226, 194, 215,
199, 190, 177, 169, 155, 114, 114, 106, 71, 83, 80, 60, 58,
57, 53, 37, 40, 21, 30, 26, 18, 18, 8, 7, 5, 9,
5, 4, 5, 1, 0, 5, 0, 1, 2]),
array([-3.87851826, -3.8052319 , -3.73194553, -3.65865916, -3.58537279,
-3.51208642, -3.43880005, -3.36551369, -3.29222732, -3.21894095,
-3.14565458, -3.07236821, -2.99908185, -2.92579548, -2.85250911,
-2.77922274, -2.70593637, -2.63265001, -2.55936364, -2.48607727,
-2.4127909 , -2.33950453, -2.26621816, -2.1929318 , -2.11964543,
-2.04635906, -1.97307269, -1.89978632, -1.82649996, -1.75321359,
-1.67992722, -1.60664085, -1.53335448, -1.46006812, -1.38678175,
-1.31349538, -1.24020901, -1.16692264, -1.09363627, -1.02034991,
-0.94706354, -0.87377717, -0.8004908 , -0.72720443, -0.65391807,
-0.5806317 , -0.50734533, -0.43405896, -0.36077259, -0.28748623,
-0.21419986, -0.14091349, -0.06762712, 0.00565925, 0.07894562,
0.15223198, 0.22551835, 0.29880472, 0.37209109, 0.44537746,
0.51866382, 0.59195019, 0.66523656, 0.73852293, 0.8118093 ,
0.88509566, 0.95838203, 1.0316684 , 1.10495477, 1.17824114,
1.25152751, 1.32481387, 1.39810024, 1.47138661, 1.54467298,
1.61795935, 1.69124571, 1.76453208, 1.83781845, 1.91110482,
1.98439119, 2.05767755, 2.13096392, 2.20425029, 2.27753666,
2.35082303, 2.4241094 , 2.49739576, 2.57068213, 2.6439685 ,
2.71725487, 2.79054124, 2.8638276 , 2.93711397, 3.01040034,
3.08368671, 3.15697308, 3.23025944, 3.30354581, 3.37683218,
3.45011855]))
箱式图¶
In [31]:
# 箱式图,绘制了数据分布情况:四等分位数绘制,同时,将异常值,进行了绘制
x = np.random.randn(500,4)
labels = list('ABCD')
_ = plt.boxplot(x,notch = True,sym = 'ro',labels=labels) # color颜色,marker
In [32]:
import pandas as pd
pd.DataFrame(x,columns=labels).describe().round(2)
Out[32]:
| A | B | C | D | |
|---|---|---|---|---|
| count | 500.00 | 500.00 | 500.00 | 500.00 |
| mean | 0.05 | 0.00 | 0.04 | 0.03 |
| std | 1.00 | 0.98 | 0.98 | 1.01 |
| min | -3.80 | -2.56 | -2.76 | -3.94 |
| 25% | -0.55 | -0.68 | -0.60 | -0.63 |
| 50% | -0.01 | 0.04 | 0.07 | 0.06 |
| 75% | 0.76 | 0.68 | 0.75 | 0.70 |
| max | 2.94 | 2.65 | 2.97 | 2.56 |
散点图¶
In [33]:
# 表示属性之间的关系
x = np.random.randn(100,2)
plt.scatter(x[:,0],x[:,1],
c = np.random.rand(100,3), # 颜色 (红,绿,蓝) 0 ~ 1
s = np.random.randint(100,300,size = 100),
alpha=0.5)
Out[33]:
<matplotlib.collections.PathCollection at 0x7f737ad2ebe0>
In [34]:
# 表示属性之间的关系
x = np.random.randn(100,2)
plt.scatter(x[:,0],x[:,0] + np.random.randn(100)*0.2,
c = np.random.rand(100,3), # 颜色 (红,绿,蓝) 0 ~ 1
s = np.random.randint(100,300,size = 100),
alpha=0.5)
Out[34]:
<matplotlib.collections.PathCollection at 0x7f737aca0f40>
饼图¶
一般饼图¶
In [35]:
p = np.random.randint(10,100,size = 5)
labels = ['一星','二星','三星','四星','五星']
plt.figure(figsize=(9,9))
_ = plt.pie(p,
labels= labels,
textprops={'family':'SimHei','fontsize':18}, # 设置字体样式
autopct='%0.2f%%', # 显示百分比
explode = [0,0,0,0,0.15],# 突出某一部分
shadow=True)
嵌套饼图¶
In [36]:
p1 = np.random.randint(30,50,size = 3) # 外圈
p2 = np.random.randint(10,80,size = 6) # 内圈
plt.figure(figsize=(9,9))
plt.pie(p1,radius=1,
autopct='%0.2f%%',
pctdistance=0.85,
labels = ['小狗','小猫','小鸟'],
wedgeprops={'linewidth':5,# 间隔的宽度
'width':0.3, # 饼图的宽度
'edgecolor':'white'},# 间隔的颜色
textprops={'family':'SimHei','fontsize':18})
_ = plt.pie(p2,
radius=0.7,
autopct='%0.2f%%',
pctdistance=0.55,
wedgeprops={'linewidth':5,# 间隔的宽度
'width':0.7, # 饼图的宽度
'edgecolor':'white'})# 间隔的颜色
plt.rcParams['font.family'] = 'SimHei' # 全局设置
plt.rcParams['font.size'] = 18
plt.legend(['小狗','小猫','小鸟'],title = '宠物类别',prop = 'SimHei',)
Out[36]:
<matplotlib.legend.Legend at 0x7f737ab73bb0>
热力图¶
In [37]:
plt.hist
Out[37]:
<function matplotlib.pyplot.hist(x: 'ArrayLike | Sequence[ArrayLike]', bins: 'int | Sequence[float] | str | None' = None, range: 'tuple[float, float] | None' = None, density: 'bool' = False, weights: 'ArrayLike | None' = None, cumulative: 'bool | float' = False, bottom: 'ArrayLike | float | None' = None, histtype: "Literal['bar', 'barstacked', 'step', 'stepfilled']" = 'bar', align: "Literal['left', 'mid', 'right']" = 'mid', orientation: "Literal['vertical', 'horizontal']" = 'vertical', rwidth: 'float | None' = None, log: 'bool' = False, color: 'ColorType | Sequence[ColorType] | None' = None, label: 'str | Sequence[str] | None' = None, stacked: 'bool' = False, *, data=None, **kwargs) -> 'tuple[np.ndarray | list[np.ndarray], np.ndarray, BarContainer | Polygon | list[BarContainer | Polygon]]'>
In [38]:
data = np.random.randn(7,7)*5
data.round(1)
Out[38]:
array([[ 0.3, -4. , -10.5, -1.9, 1.4, -1.3, 9.1],
[ 0.3, -0.5, -3.6, -3.4, -3.1, -2.8, -10.3],
[ -2.2, 7.2, -10.3, -6.9, -0.3, -4.9, 0. ],
[ 3.3, 3.4, 7.6, 6.9, 2.4, -0.4, 1.2],
[-13.3, 1.8, 3.8, -5.3, -3.7, -10.8, 4.7],
[ -1.8, -2.2, -0.8, 0.7, -4.3, 3.2, -1. ],
[ -8. , -4.2, -0.7, 0.5, 2. , -0.9, 3.1]])
In [39]:
plt.figure(figsize=(9,9))
plt.imshow(data,cmap=plt.cm.RdBu_r) # 展示图片
for i in range(7):
for j in range(7):
plt.text(x = j,y = i,s=round(data[i,j],1),ha = 'center')
面积图¶
In [40]:
days = np.arange(1,6)
working = np.array([8,9,7,8,11])
sleeping = np.array([6,7,5,8,7])
eating = np.array([3,2,3,1,3])
playing = np.array([7,6,9,7,3])
plt.figure(figsize=(9,6))
plt.stackplot(days,working,sleeping,eating,playing) # 堆叠
plt.legend(['working','sleeping','eating','playing'])
Out[40]:
<matplotlib.legend.Legend at 0x7f738000ac10>
蜘蛛图¶
In [41]:
labels = np.array(['个人能力','IQ','EQ','团队意识','持续学习','解决问题能力'])
angles = np.arange(0,2*np.pi,np.pi/3) # 弧度
stats = np.random.randint(50,120,size = 6) # 个人能力强弱
# 首尾相连,和原来相比,长度增加了一个
angles = np.concatenate([angles,angles[[0]]])
stats = np.concatenate([stats,stats[[0]]])
plt.figure(figsize=(8,8))
axes = plt.subplot(111,polar = True) # 极坐标图
axes.plot(angles,stats,marker = 'o',lw = 2) # 折线图
axes.fill(angles,stats,alpha = 0.2)
axes.set_thetagrids(angles[:-1]*180/np.pi,labels=labels,fontsize = 18) # 设置了角度显示
_ = axes.set_rgrids([10,30,50,70,90,110])
3D图形¶
In [42]:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randint(0,10,size = 50)
y = np.random.randint(0,10,size = 50)
z = np.random.randint(0,10,size = 50)
plt.plot(x,y,z)
Out[42]:
[<matplotlib.lines.Line2D at 0x7f737aa82be0>, <matplotlib.lines.Line2D at 0x7f737aa82c10>]
In [43]:
from mpl_toolkits.mplot3d.axes3d import Axes3D # 绘制3D图形对象
x = np.linspace(0,20,300)
y = np.sin(x)
z = np.cos(x)
fig = plt.figure(figsize=(9,6)) # 二维的
ax3 = Axes3D(fig) # 二维视图,放到3D中,变成3D视图
ax3.plot(x,y,z,color = 'red')
# rand 返回数据 0 ~ 1之间
ax3.scatter(np.random.rand(50)*20,
np.random.rand(50),
np.random.rand(50),s = 100,color = 'green')
Out[43]:
<mpl_toolkits.mplot3d.art3d.Path3DCollection at 0x7f737aa04f70>
<Figure size 900x600 with 0 Axes>
In [44]:
season = np.arange(1,5) # 四个季度
# 每个季度3个月,每个月都要销量
fig = plt.figure(figsize=(9,6))
ax3 = Axes3D(fig)
for s in season:
ax3.bar(np.arange(1,4),# 一个季度:三个月。横坐标
np.random.randint(50,100,size = 3),# 高度,销量,纵坐标
zs = s, # 偏移量
zdir = 'x',# 排列方向
alpha = 0.5)
ax3.set_xlabel('X',fontsize = 18,color = 'red')
ax3.set_xticks([1,2,3,4])
ax3.set_xticklabels(['一季度','二季度','三季度','四季度'])
plt.rcParams['font.size'] = 18
_ = ax3.set_yticks([1,2,3])
<Figure size 900x600 with 0 Axes>
实战-拉勾网数据分析师招聘数据分析
加载、查看、去重¶
In [107]:
import numpy as np
import pandas as pd
job = pd.read_csv('./lagou2020.csv')
job.drop_duplicates(inplace=True)
job.reset_index(inplace=True) # 行索引重置:0~最后,从0开始编号
job.head()
Out[107]:
| index | positionName | companyShortName | city | companySize | education | financeStage | industryField | salary | workYear | hitags | companyLabelList | job_detail | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 高级数据分析师 | 拉勾网 | 北京 | 500-2000人 | 本科 | D轮及以上 | 企业服务 | 25k-35k | 5-10年 | ["免费下午茶","ipo倒计时","bat背景","地铁周边","每天管两餐","定期团建... | ["五险一金","弹性工作","带薪年假","免费两餐"] | \n1.搭建数据指标框架,完整并准确反映业务趋势和变化,及时发现和定位问题\n2.独立完成数... |
| 1 | 1 | 数据分析师 | OK Group | 北京 | 500-2000人 | 大专 | B轮 | 金融 | 25k-45k | 5-10年 | NaN | ["节日礼物","年度旅游","扁平管理","领导好"] | \n工作职责:\n1. 负责建立交易平台日常分析体系,包括核心指标体系、报表体系,专题活动分... |
| 2 | 2 | 高级数据分析师 | 金山办公软件 | 北京 | 2000人以上 | 本科 | 上市公司 | 移动互联网 | 15k-25k | 3-5年 | NaN | ["年底双薪","节日礼物","技能培训","绩效奖金"] | \n职位描述:1.对亿计的办公用户数据进行深度挖掘,引导产品、运营,并能实际应用到业务中带来... |
| 3 | 3 | 数据分析师 | 金山办公软件 | 北京 | 2000人以上 | 本科 | 上市公司 | 移动互联网 | 15k-25k | 1-3年 | NaN | ["年底双薪","节日礼物","技能培训","绩效奖金"] | \n工作职责:-负责日常运营、业务数据等分析-针对产品需求做深入的数据分析报告,分析用户行为... |
| 4 | 4 | 数据分析师 | 京东集团 | 北京 | 2000人以上 | 本科 | 上市公司 | 电商 | 15k-30k | 3-5年 | ["免费班车","免费体检","地铁周边"] | ["五险一金","带薪年假","免费班车","定期体检"] | \n【数据分析师岗】\n岗位要求:\n1、构建及维护客户体验相关数据报表平台;\n2、与大数... |
In [108]:
job.companySize.unique()
Out[108]:
array(['500-2000人', '2000人以上', '150-500人', '50-150人', '15-50人', '少于15人'],
dtype=object)
过滤非数据分析岗位¶
In [109]:
# contains这个是字符串中方法,进行逻辑判断,是否含有
cond = job['positionName'].str.contains('数据分析')
job = job[cond]
job.reset_index(inplace=True) # 重置行索引
job
Out[109]:
| level_0 | index | positionName | companyShortName | city | companySize | education | financeStage | industryField | salary | workYear | hitags | companyLabelList | job_detail | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 高级数据分析师 | 拉勾网 | 北京 | 500-2000人 | 本科 | D轮及以上 | 企业服务 | 25k-35k | 5-10年 | ["免费下午茶","ipo倒计时","bat背景","地铁周边","每天管两餐","定期团建... | ["五险一金","弹性工作","带薪年假","免费两餐"] | \n1.搭建数据指标框架,完整并准确反映业务趋势和变化,及时发现和定位问题\n2.独立完成数... |
| 1 | 1 | 1 | 数据分析师 | OK Group | 北京 | 500-2000人 | 大专 | B轮 | 金融 | 25k-45k | 5-10年 | NaN | ["节日礼物","年度旅游","扁平管理","领导好"] | \n工作职责:\n1. 负责建立交易平台日常分析体系,包括核心指标体系、报表体系,专题活动分... |
| 2 | 2 | 2 | 高级数据分析师 | 金山办公软件 | 北京 | 2000人以上 | 本科 | 上市公司 | 移动互联网 | 15k-25k | 3-5年 | NaN | ["年底双薪","节日礼物","技能培训","绩效奖金"] | \n职位描述:1.对亿计的办公用户数据进行深度挖掘,引导产品、运营,并能实际应用到业务中带来... |
| 3 | 3 | 3 | 数据分析师 | 金山办公软件 | 北京 | 2000人以上 | 本科 | 上市公司 | 移动互联网 | 15k-25k | 1-3年 | NaN | ["年底双薪","节日礼物","技能培训","绩效奖金"] | \n工作职责:-负责日常运营、业务数据等分析-针对产品需求做深入的数据分析报告,分析用户行为... |
| 4 | 4 | 4 | 数据分析师 | 京东集团 | 北京 | 2000人以上 | 本科 | 上市公司 | 电商 | 15k-30k | 3-5年 | ["免费班车","免费体检","地铁周边"] | ["五险一金","带薪年假","免费班车","定期体检"] | \n【数据分析师岗】\n岗位要求:\n1、构建及维护客户体验相关数据报表平台;\n2、与大数... |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1647 | 3177 | 3352 | 数据分析师 | 华泛信息 | 苏州 | 2000人以上 | 大专 | 不需要融资 | 移动互联网,其他 | 10k-15k | 1-3年 | NaN | ["技能培训","节日礼物","带薪年假","绩效奖金"] | \n岗位职责:\n深入了解项目组的业务需求,在此基础上进行数据收集、数据分析、商业报告的撰写... |
| 1648 | 3178 | 3353 | 大数据分析师 | 德融嘉信 | 苏州 | 50-150人 | 本科 | 不需要融资 | 移动互联网 | 6k-12k | 1-3年 | NaN | [] | \n岗位职责:\n1. 开展业务专题分析,使用数据挖掘各类算法构建相关的业务模型,完成业务分... |
| 1649 | 3404 | 3580 | ETL/大数据/数据分析/实施 | 格蒂电力 | 天津 | 500-2000人 | 大专 | 未融资 | 企业服务 | 6k-12k | 3-5年 | NaN | ["技能培训","带薪年假","绩效奖金","岗位晋升"] | \n工作职责\n1. 负责数据接入、数据整合中的链路配置与调度配置工作。\n职位要求\n... |
| 1650 | 3405 | 3581 | 数据分析师 | 吉城美家 | 天津 | 2000人以上 | 本科 | 未融资 | 移动互联网 | 7k-14k | 1-3年 | NaN | ["五险一金","岗位晋升"] | \n负责站点日常数据分析、提前通过数据分析对业务有预测性、通过数据说话、解决站点管理问题、\n |
| 1651 | 3406 | 3582 | 数据分析支持 | 云链供应链 | 天津 | 15-50人 | 本科 | 未融资 | 金融,企业服务 | 4k-6k | 1-3年 | NaN | [] | \n 岗位职责:\n1、负责部门日常数据报表的制定、维护、优化;\n2、支持运... |
1652 rows × 14 columns
薪水¶
In [110]:
# applymap和map类似的,map操作Series,applymap操作的DataFrame
# job['salary'] = job['salary'].str.lower().str.extract(r'(\d+)[k]-(\d+)[k]')\
# .applymap(lambda x : int(x)).mean(axis = 1)
job['salary'] = job['salary'].str.lower().str.extract(r'(\d+)[k]-(\d+)[k]')\
.map(lambda x : int(x)).mean(axis = 1)
In [111]:
job
Out[111]:
| level_0 | index | positionName | companyShortName | city | companySize | education | financeStage | industryField | salary | workYear | hitags | companyLabelList | job_detail | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 高级数据分析师 | 拉勾网 | 北京 | 500-2000人 | 本科 | D轮及以上 | 企业服务 | 30.0 | 5-10年 | ["免费下午茶","ipo倒计时","bat背景","地铁周边","每天管两餐","定期团建... | ["五险一金","弹性工作","带薪年假","免费两餐"] | \n1.搭建数据指标框架,完整并准确反映业务趋势和变化,及时发现和定位问题\n2.独立完成数... |
| 1 | 1 | 1 | 数据分析师 | OK Group | 北京 | 500-2000人 | 大专 | B轮 | 金融 | 35.0 | 5-10年 | NaN | ["节日礼物","年度旅游","扁平管理","领导好"] | \n工作职责:\n1. 负责建立交易平台日常分析体系,包括核心指标体系、报表体系,专题活动分... |
| 2 | 2 | 2 | 高级数据分析师 | 金山办公软件 | 北京 | 2000人以上 | 本科 | 上市公司 | 移动互联网 | 20.0 | 3-5年 | NaN | ["年底双薪","节日礼物","技能培训","绩效奖金"] | \n职位描述:1.对亿计的办公用户数据进行深度挖掘,引导产品、运营,并能实际应用到业务中带来... |
| 3 | 3 | 3 | 数据分析师 | 金山办公软件 | 北京 | 2000人以上 | 本科 | 上市公司 | 移动互联网 | 20.0 | 1-3年 | NaN | ["年底双薪","节日礼物","技能培训","绩效奖金"] | \n工作职责:-负责日常运营、业务数据等分析-针对产品需求做深入的数据分析报告,分析用户行为... |
| 4 | 4 | 4 | 数据分析师 | 京东集团 | 北京 | 2000人以上 | 本科 | 上市公司 | 电商 | 22.5 | 3-5年 | ["免费班车","免费体检","地铁周边"] | ["五险一金","带薪年假","免费班车","定期体检"] | \n【数据分析师岗】\n岗位要求:\n1、构建及维护客户体验相关数据报表平台;\n2、与大数... |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1647 | 3177 | 3352 | 数据分析师 | 华泛信息 | 苏州 | 2000人以上 | 大专 | 不需要融资 | 移动互联网,其他 | 12.5 | 1-3年 | NaN | ["技能培训","节日礼物","带薪年假","绩效奖金"] | \n岗位职责:\n深入了解项目组的业务需求,在此基础上进行数据收集、数据分析、商业报告的撰写... |
| 1648 | 3178 | 3353 | 大数据分析师 | 德融嘉信 | 苏州 | 50-150人 | 本科 | 不需要融资 | 移动互联网 | 9.0 | 1-3年 | NaN | [] | \n岗位职责:\n1. 开展业务专题分析,使用数据挖掘各类算法构建相关的业务模型,完成业务分... |
| 1649 | 3404 | 3580 | ETL/大数据/数据分析/实施 | 格蒂电力 | 天津 | 500-2000人 | 大专 | 未融资 | 企业服务 | 9.0 | 3-5年 | NaN | ["技能培训","带薪年假","绩效奖金","岗位晋升"] | \n工作职责\n1. 负责数据接入、数据整合中的链路配置与调度配置工作。\n职位要求\n... |
| 1650 | 3405 | 3581 | 数据分析师 | 吉城美家 | 天津 | 2000人以上 | 本科 | 未融资 | 移动互联网 | 10.5 | 1-3年 | NaN | ["五险一金","岗位晋升"] | \n负责站点日常数据分析、提前通过数据分析对业务有预测性、通过数据说话、解决站点管理问题、\n |
| 1651 | 3406 | 3582 | 数据分析支持 | 云链供应链 | 天津 | 15-50人 | 本科 | 未融资 | 金融,企业服务 | 5.0 | 1-3年 | NaN | [] | \n 岗位职责:\n1、负责部门日常数据报表的制定、维护、优化;\n2、支持运... |
1652 rows × 14 columns
技能要求¶¶
Python
SQL
Tableau
Excel
SPSS/SAS
In [112]:
job['job_detail'] = job['job_detail'].str.lower() # 变成小写
job['Python'] = job['job_detail'].map(lambda x :1 if 'python' in x else 0)
job['SQL'] = job['job_detail'].map(lambda x : 1 if 'sql' in x else 0)
job['Tableau'] = job['job_detail'].map(lambda x :1 if 'tableau' in x else 0)
job['Excel'] = job['job_detail'].map(lambda x :1 if 'excel' in x else 0)
job['SPSS/SAS'] = job['job_detail'].map(lambda x :1 if ('spss' in x) or ('sas' in x) else 0)
行业信息¶
In [113]:
# 行业信息转化,明确
def convert(x):
field = x.split(',')
if (field[0] == '移动互联网') & (len(field) > 1):
return field[1]
else:
return field[0]
job['industryField'] = job.industryField.map(convert)
In [114]:
job.to_excel('./数据分析师薪资.xlsx',index=False)
各城市对数据分析岗位的需求量¶
两种常用颜色:浅蓝色: #3c7f99 ,淡黄色:#c5b783
In [115]:
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['font.size'] = 18
In [116]:
data = job.city.value_counts()
plt.figure(figsize=(12,9))
plt.barh(y = data.index[::-1],width=data[::-1],color = '#3c7f99')
plt.box(False) # 去掉边框
plt.grid(axis='x',color = '#3c7f99') # 网格线
plt.title(label=' 各城市数据分析师岗位需求量 ',
fontsize = 32,
backgroundcolor = '#c5b783',
color = 'white',
weight = 'bold',
pad = 30) # 标题和上边界的间隔
Out[116]:
Text(0.5, 1.0, ' 各城市数据分析师岗位需求量 ')
不同领域对数据分析师需求情况¶
In [117]:
data = job.industryField.value_counts()[:10]
plt.figure(figsize=(12,9))
plt.barh(y = data.index[::-1],width=data[::-1],color = '#3c7f99')
plt.grid(linestyle = '--',color = '#3c7f99',axis = 'x')
plt.title(label=' 各领域数据分析师需求量 ',
fontsize = 32,
color = 'white',
backgroundcolor ='#c5b783',pad = 30 )
Out[117]:
Text(0.5, 1.0, ' 各领域数据分析师需求量 ')
各城市薪资状况¶
In [118]:
salary = job.groupby(by = 'city')['salary'].mean().sort_values()
plt.figure(figsize=(12,9))
plt.bar(x = salary.index,height=salary,
color = plt.cm.RdBu_r(np.linspace(0,1,salary.size)))
plt.title(label = ' 各城市薪资状况 ',
fontsize = 32,
color = 'white',backgroundcolor = '#c5b783',weight = 'bold',pad = 30)
plt.box(False)
plt.grid(axis = 'y',color = 'k')
plt.tick_params(labelsize = 18,rotation = 60)
各城市工作年限与薪资关系¶
In [119]:
# 透视表
# job.pivot_table(values='salary',index='city',columns='workYear').round(1)
# 分组聚合
years_salary = job.groupby(by = ['city','workYear'])['salary']\
.mean().round(1).unstack().sort_values(by = '5-10年',ascending = False)
year_salary = years_salary[['应届毕业生','1-3年','3-5年','5-10年']].iloc[1:]
nd = year_salary.values
data = np.repeat(nd,4,axis = 1) # 列进行了复制4份,绘制图形美观
plt.figure(figsize=(12,9))
plt.imshow(data,cmap = plt.cm.RdBu_r)
plt.xticks([1.5,5.5,9.5,13.5],year_salary.columns)
plt.yticks(np.arange(12),year_salary.index)
h,w = data.shape # h = 13,w = 16(4*4)
for x in range(w):
for y in range(h):
if (x%4 == 0) and (~np.isnan(data[y,x])):
plt.text(x+1.5,y,data[y,x],ha = 'center',va = 'center')
_ = plt.title(label = ' 工作经验和薪资关系 ',fontsize = 32,pad = 30)
学历情况¶
In [120]:
edu = job['education'].value_counts()
plt.figure(figsize=(9,9))
_ = plt.pie(edu,autopct='%0.2f%%',
labels=edu.index,wedgeprops={'width':0.5},
pctdistance=0.75)
_ = plt.title(label=' 数据分析师学历情况 ',fontsize = 32,pad = 30)
技能要求¶
In [121]:
cond1 = job['Python'].astype('boolean') # 根据条件筛选
cond2 = job['SQL'].astype('boolean') # 根据条件筛选
cond3 = job['Excel'].astype('boolean') # 根据条件筛选
cond4 = job['SPSS/SAS'].astype('boolean') # 根据条件筛选
d1 = job[cond1]['salary']
d2 = job[cond2]['salary']
d3 = job[cond3]['salary']
d4 = job[cond4]['salary']
plt.figure(figsize=(12,9))
a = plt.boxplot([d1,d2,d3,d4],vert = False,labels=['Python','SQL','Excel','SPSS/SAS'])
plt.grid(axis = 'x',color = 'k',alpha = 0.3)
_ = plt.xticks(np.arange(0,161,step = 20),
[str(i) + 'K' for i in np.arange(0,161,step = 20)])
大厂对技能要求¶
In [122]:
colors = ['#ff0000', '#ffa500', '#c5b783', '#3c7f99', '#0000cd']
In [123]:
cond = job.companySize == '2000人以上'
bc = job[cond] # 大公司筛选
In [124]:
data = bc[['Python','SQL','Tableau','Excel','SPSS/SAS']].sum()
data
Out[124]:
Python 278 SQL 392 Tableau 91 Excel 201 SPSS/SAS 105 dtype: int64
In [125]:
plt.figure(figsize=(12,9))
plt.bar(x = np.arange(5),
height=data,
tick_label = ['Python','SQL','Tableau','Excel','SPSS/SAS'],
color = colors,width = 0.5)
plt.title(label=' 大公司对技能要求 ',fontsize = 32,pad = 30)
plt.grid(axis = 'y')
不同规模公司招人要求¶
In [126]:
workYear_map = {
"应届毕业生": 1,
"1年以下": 2,
"1-3年": 3,
"3-5年": 4,
"5-10年": 5,
}
color_map = {
5:"#ff0000",
4:"#ffa500",
3:"#c5b783",
2:"#3c7f99",
1:"#0000cd"}
cond = job.workYear.isin(workYear_map) # 判断是否在数据集合中,True,Flase
job2 = job[cond]
In [127]:
job2 = job2.copy()
job2['workYearNum'] = job2['workYear'].map(workYear_map)
# 将 str类型转换成了类别性,特殊的数据类型,排序
job2['companySize'] = job2['companySize'].astype('category')
数据分析三剑客:NumPy、pandas、Matplotlib
In [128]:
list(color_map.values())[::-1]
job2.salary
Out[128]:
0 30.0
1 35.0
2 20.0
3 20.0
4 22.5
...
1647 12.5
1648 9.0
1649 9.0
1650 10.5
1651 5.0
Name: salary, Length: 1475, dtype: float64
In [129]:
from matplotlib import gridspec
plt.figure(figsize=(12,9))
list_num = ['2000人以上','500-2000人','150-500人','50-150人','15-50人','少于15人']
# re order 重新排序
job2.companySize.cat.reorder_categories(list_num)##, inplace = True
job2.sort_values(by = 'companySize',ascending=False,inplace = True)##
gs = gridspec.GridSpec(10,1) # 整张图片分成了10份,10行
plt.subplot(gs[:8]) # 子视图,占位置上面的8行
plt.scatter(x =job2.salary ,
y = job2.companySize,
c = job2.workYearNum.map(color_map),
s = job2.workYearNum*100,alpha=0.35)
plt.scatter(x =job2.salary ,
y = job2.companySize,
c = job2.workYearNum.map(color_map)) # 点中点效果
plt.xticks(np.arange(0,161,step = 20),[str(i) + 'K' for i in np.arange(0,161,20)])
plt.grid(axis = 'x')
plt.box(False)
plt.title(label=' 不同规模公司招聘要求 ',fontsize = 32,pad = 30)
plt.subplot(gs[-1]) # 最后一行
x = np.arange(1,6)
y = np.zeros(5)
plt.scatter(x,y,c = list(color_map.values())[::-1],
s = x*100,alpha= 0.35)
plt.scatter(x,y,c = list(color_map.values())[::-1])
plt.yticks([0],['经验'])
plt.xticks(x,workYear_map.keys())
plt.box(False)
In [130]:
workYear_map.keys()
Out[130]:
dict_keys(['应届毕业生', '1年以下', '1-3年', '3-5年', '5-10年'])
In [131]:
color_map.values()
Out[131]:
dict_values(['#ff0000', '#ffa500', '#c5b783', '#3c7f99', '#0000cd'])