利用python进行数据分析(绘图与可视化3)

第九章绘图与可视化

%matplotlib notebook

9.1 简明matplotlib API入门

  • 使用Jupyter notebook时有个细节需要注意,在每个单元格运行后,图表被重置,因此对于更复杂的图表,你必须将所有的绘图命令放在单个的notebook单元格中
import matplotlib.pyplot as plt
import numpy as np
data = np.arange(10)
data
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
plt.plot(data)

9.1.1 图片与子图

  • matplotlib所绘制的图位于图片(Figure)对象中
  • pyplot.subplots选项
参数描述
nrows子图的行数
ncols子图的列数
sharex所有子图使用相同的x轴刻度(调整xlim会影响所有子图)
sharey所有子图使用相同的y轴刻度(调整ylim会影响所有子图)
subplot_ kw传入add_ subplot 的关键字参数字典,用于生成子图
**fig_ _kW在生成图片时使用的额外关键字参数,例如plt. subplots (2,2,figsize= (8,6))
#你可以使用plt.figure生成一个新的图片
fig = plt.figure()
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
plt.plot(np.random.randn(50).cumsum(),'k--')
_ = ax1.hist(np.random.randn(100),bins=20,color='k',alpha=0.3)
ax2.scatter(np.arange(30),np.arange(30)+3*np.random.randn(30))
fig,axes = plt.subplots(2,3,sharex=True,sharey=True)
9.1.1.1 调整子图周围的间距
  • 你可以使用图对象上的subplots_adjust方法更改间距,也可以用作顶层函数
#wspace和hspace分别控制的是图片的宽度和高度百分比,以用作子图间的间距
plt.subplots_adjust(left=None,bottom=None,right=None,top=None
                    ,wspace=None,hspace=None,)
fig,axes = plt.subplots(2,2,sharex=True,sharey=True)
for i in range(2):
    for j in range(2):
        axes[i,j].hist(np.random.randn(500),bins=50,color='k',alpha=0.5)
plt.subplots_adjust(wspace=0,hspace=0)

9.1.2 颜色、标记和线类型

from numpy.random import randn
fig = plt.figure()
plt.plot(randn(30).cumsum(),'ko--')
fig = plt.figure()
data = np.random.randn(30).cumsum()
plt.plot(data,'k--',label='Default')
plt.plot(data,'k-',drawstyle='steps-post',label='step-post')
plt.legend(loc='best')

9.1.3 刻度、标签和图例

9.1.3.1 设置标题、轴
  • 要改变x轴刻度,最简单的方式是使用set_xticks和set_xticklabels
  • set_xticks表示在数据范围内设定刻度的位置,默认情况下,这些刻度也有标签
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(np.random.randn(1000).cumsum())
ticks = ax.set_xticks([0,250,500,750,1000])
labels = ax.set_xticklabels(['one','two','three','four','five'],rotation=30,fontsize='small')
ax.set_title('My first matplotlib plot')
ax.set_xlabel('stages')

9.1.3.2 添加图例

from numpy.random import randn
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.plot(randn(1000).cumsum(),'k',label='one')
ax.plot(randn(1000).cumsum(),'k--',label='two')
ax.plot(randn(1000).cumsum(),'k.',label='three')
ax.legend(loc='best')
ax.text(x,y,'hello world',family='monospace',fontsize=10)

9.1.4 注释与子图加工

  • 使用text、arrow和annote方法来添加注释和文本。
  • text在图表上给定的坐标(x, y),根据可选的定制样式绘制文本
data = pd.read_csv('examples/spx.csv',index_col=0,parse_dates=True)
spx = data['SPX']
from datetime import datetime
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
spx.plot(ax=ax,style='k-')
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
rect = plt.Rectangle((0.2,0.75),0.4,0.15,color='k',alpha=0.3)
circ = plt.Circle((0.7,0.2),0.15,color='b',alpha=0.3)
pgon = plt.Polygon([[0.15,0.15],[0.35,0.4],[0.2,0.6]],color='g',alpha=0.5)

ax.add_patch(rect)
ax.add_patch(circ)
ax.add_patch(pgon)

plt.savefig('figpath.png',dpi=400,bbox_inches='tight')

9.1.5 将图片保存到文件

  • 你可以使用plt.savefig将活动图片保存到文件。这个方法等价于图片对象的savefig实例方法
#saveifg并非一定是写到硬盘的,它可以将图片写入到所有的文件型对象中
from io import BytesIO
buffer = BytesIO()
plt.savefig(buffer)
plt_data = buffer.getvalue()

9.1.6 matplotlib设置

  • 使用rc方法是使用Python编程修改配置的一种方式

9.2 使用pandas和seaborn绘图

9.2.1 折线图

  • 默认情况下,plot()绘制的是折线图
  • Series对象的索引传入matplotlib作为绘图的x轴,你可以通过传入use_index=False来禁用这个功能
  • x轴的刻度和范围可以通过xticks和xlim选项进行调整,相应地y轴使用yticks和ylim进行调整。
  • Series.plot方法参数
参数描述
label图例标签绘图所用的matplotib子图对象;如果没传值,则使用当前活动的matplotlib子图
style传给matplotlib的样式字符串,比如’ko–’
alpha图片不透明度(从0到1)
kind可以是’area’. ‘bar’. ‘barh’. ’ density’、‘hist’.,kde’. ’ line’. ‘pie’
logy在y轴上使用对数缩放
use_ index使用对象索引刻度标签
rot刻度标签的旋转(0 到360)
xticks用于x轴刻度的值
yticks用于y轴刻度的值
xlimx轴范围(例如[0,10])
ylimy轴范围
grid展示轴网格(默认是打开的)
#Series对象的索引传入matplotlib作为绘图的x轴,
#你可以通过传入use_index=False来禁用这个功能
s = pd.Series(np.random.randn(10).cumsum(),
             index=np.arange(0,100,10))
s.plot()
s
0     0.168491
10   -0.301518
20   -1.247281
30   -0.589754
40   -0.974903
50   -0.322050
60   -0.330096
70   -0.729736
80   -1.298080
90   -1.207302
dtype: float64
df = pd.DataFrame(np.random.randn(10,4).cumsum(0),
                  columns=['A','B','C','D'],
                  index=np.arange(0,100,10))
df.plot()
df
ABCD
00.353917-0.1009112.919896-0.008181
101.240468-0.2378932.654006-0.272069
200.024472-2.6667053.9983380.151660
301.694991-3.0068363.5465081.095049
401.567156-2.6112472.9587820.730146
502.757183-4.0330315.6638880.594940
603.556481-1.9690826.8193541.949167
704.763156-1.8636286.1631303.080424
805.675488-3.0514506.5322813.146377
904.219759-1.9978047.6164935.069851
```python df.plot.line() ``` ### 9.2.2 柱状图 - plot.bar()和plot.barh()可以分别绘制垂直和水平的柱状图
fig,axes = plt.subplots(2,1)
data = pd.Series(np.random.rand(16),index=list('abcdefghijklmnop'))
data.plot.bar(ax=axes[0],color='k',alpha=0.7)
data.plot.barh(ax=axes[1],color='k',alpha=0.7)
df = pd.DataFrame(np.random.rand(6,4),
                 index=['one','two','three','four','five','six'],
                 columns=pd.Index(['A','B','C','D'],name='Genus'))
df
df.plot.bar()
#可以通过传递stacked=True来生成堆积柱状图,会使得每一行的值堆积在一起
df.plot.bar(stacked=True,alpha=0.5)
df.plot.barh(stacked=True,alpha=0.5)
#使用value_counts: s.value_counts().plot.bar()可以有效地对Series值频率进行可视化
tips = pd.read_csv('examples/tips.csv')
tips.head()
total_billtipsmokerdaytimesize
016.991.01NoSunDinner2
110.341.66NoSunDinner3
221.013.50NoSunDinner3
323.683.31NoSunDinner2
424.593.61NoSunDinner4
pay_counts = pd.crosstab(tips['day'],tips['size'])
pay_counts
size123456
day
Fri1161100
Sat253181310
Sun039151831
Thur1484513
party_counts = pay_counts.loc[:,2:5]
party_counts
size2345
day
Fri16110
Sat5318131
Sun3915183
Thur48451
party_counts.sum(1)
day
Fri     18
Sat     85
Sun     75
Thur    58
dtype: int64
#标准化至和为1
party_pcts = party_counts.div(party_counts.sum(1),axis=0)
party_pcts.plot.bar()
party_pcts
size2345
day
Fri0.8888890.0555560.0555560.000000
Sat0.6235290.2117650.1529410.011765
Sun0.5200000.2000000.2400000.040000
Thur0.8275860.0689660.0862070.017241
import seaborn as sns
tips
total_billtipsmokerdaytimesize
016.991.01NoSunDinner2
110.341.66NoSunDinner3
221.013.50NoSunDinner3
323.683.31NoSunDinner2
424.593.61NoSunDinner4
.....................
23929.035.92NoSatDinner3
24027.182.00YesSatDinner2
24122.672.00YesSatDinner2
24217.821.75NoSatDinner2
24318.783.00NoThurDinner2

244 rows × 6 columns

#柱子上画出的黑线代表的是95%的置信区间(置信区间可以通过可选参数进行设置)。
tips['tip_pct'] = tips['tip']/(tips['total_bill']-tips['tip'])
sns.barplot(x='tip_pct',y='day',data=tips,orient='h')
tips.head()
total_billtipsmokerdaytimesizetip_pct
016.991.01NoSunDinner20.063204
110.341.66NoSunDinner30.191244
221.013.50NoSunDinner30.199886
323.683.31NoSunDinner20.162494
424.593.61NoSunDinner40.172069
#seaborn.barplot拥有一个hue选项,允许我们通过一个额外的分类值将数据分离
sns.barplot(x='tip_pct',y='day',data=tips,orient='h',hue='time')
sns.set(style='white')

9.2.3 直方图和密度图

  • 直方图是一种条形图,用于给出值频率的离散显示。
  • 数据点被分成离散的,均匀间隔的箱,并且绘制每个箱中数据点的数量。
tips['tip_pct'].plot.hist(bins=50)
#密度图也被称为内核密度估计图(KDE)。plot.kde使用传统法定混合法估计绘制密度图
tips['tip_pct'].plot.density()
#distplot方法可以绘制直方图和连续密度估计,
#通过distplot方法seaborn使直方图和密度图的绘制更为简单
comp1 = np.random.normal(0,1,size=200)
comp1[:10]
array([ 1.79433075,  0.71950576,  1.85644046,  1.70894088,  0.15187961,
       -0.65322128,  1.82576072,  0.41054884, -0.3166894 , -0.27848755])
comp2 = np.random.normal(10,2,size=200)
comp2[:10]
array([ 9.17557046, 12.23272092, 10.79859503,  8.79727061, 10.2600498 ,
        9.93102067,  7.30060627, 12.17173317, 11.23735906,  8.1658837 ])
values = pd.DataFrame(np.concatenate([comp1,comp2]))
values.head()
0
01.794331
10.719506
21.856440
31.708941
40.151880
sns.distplot(values,bins=100,color='k')
D:\Anaconda3\lib\site-packages\seaborn\distributions.py:2557: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).
  warnings.warn(msg, FutureWarning)
sns.displot(values)

9.2.4 散点图或点图

  • 点图或散点图可以用于检验两个一维数据序列之间的关系
macro = pd.read_csv('examples/macrodata.csv')
macro.head()
yearquarterrealgdprealconsrealinvrealgovtrealdpicpim1tbilrateunemppopinflrealint
01959.01.02710.3491707.4286.898470.0451886.928.98139.72.825.8177.1460.000.00
11959.02.02778.8011733.7310.859481.3011919.729.15141.73.085.1177.8302.340.74
21959.03.02775.4881751.8289.226491.2601916.429.35140.53.825.3178.6572.741.09
31959.04.02785.2041753.7299.356484.0521931.329.37140.04.335.6179.3860.274.06
41960.01.02847.6991770.5331.722462.1991955.529.54139.63.505.2180.0072.311.19
data = macro[['cpi','m1','tbilrate','unemp']]
data.head()
cpim1tbilrateunemp
028.98139.72.825.8
129.15141.73.085.1
229.35140.53.825.3
329.37140.04.335.6
429.54139.63.505.2
trans_data = np.log(data).diff().dropna()
trans_data.head()
cpim1tbilrateunemp
10.0058490.0142150.088193-0.128617
20.006838-0.0085050.2153210.038466
30.000681-0.0035650.1253170.055060
40.005772-0.002861-0.212805-0.074108
50.0003380.004289-0.2669460.000000
#导入matplotlib相关库
import matplotlib.pyplot as plt

# 中文乱码的处理
plt.rcParams['font.sans-serif'] =['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
sns.regplot('m1','unemp',data=trans_data)
plt.title('这是标题,太多英文字母了,不想打')
#成对图或散点图矩阵
sns.pairplot(trans_data,diag_kind='kde',plot_kws={'alpha':0.2})

9.2.5 分面网格和分类数据

  • seaborn拥有一个有效的内建函数factorplot,它可以简化多种分面绘图
tips.head()
total_billtipsmokerdaytimesizetip_pct
016.991.01NoSunDinner20.063204
110.341.66NoSunDinner30.191244
221.013.50NoSunDinner30.199886
323.683.31NoSunDinner20.162494
424.593.61NoSunDinner40.172069
sns.factorplot(x='day',y='tip_pct',hue='time',col='smoker',kind = 'bar',data=tips[tips.tip_pct<1])
sns.factorplot(x='day',y='tip_pct',row='time',col='smoker',kind = 'bar',data=tips[tips.tip_pct<1])
sns.factorplot(x='day',y='tip_pct',kind = 'box',data=tips[tips.tip_pct<1])

9.3 其他Python可视化工具

  • 借助像Bokeh(http://bokeh.pydata.org/)和Plotly(https://github.com/plotly/plotly.py)这样的工具,在web浏览器中创建动态的、交互式图像的工作现在已经可以实现。

9.4 本章小结

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值