pandas笔记:ch08:绘图和可视化
ch08
绘图和可视化¶
Plotting and Visualization
from __future__ import division
from numpy.random import randn
import numpy as np
import os
import matplotlib.pyplot as plt
np.random.seed(12345)
plt.rc('figure', figsize=(10, 6))
from pandas import Series, DataFrame
import pandas as pd
np.set_printoptions(precision=4)
from matplotlib.pyplot import *
%matplotlib nbagg
%pylab nbagg
plt.rc('figure', figsize=(10, 5))
'在notebook下使用matplotlib的初始化环境'
%pylab notebook
#%matplotlib inline
testplt = plot(np.arange(10))
%matplotlib notebook
%matplotlib --list
%pwd
'gui事件循环情况'
%gui?
matplotlib API 入门¶
import matplotlib.pyplot as plt
Figures 和 Subplots¶
'用plt.figure创建一个新的Figure'
fig = plt.figure()
'Figure.add_subplot()创建一个或多个subplot,并返回AxesSubplot对象'
'这里创建2*2=4个窗口,并激活第一个窗口'
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
'绘图命令会在当前激活的subplot绘图'
from numpy.random import randn
plt.plot(randn(50).cumsum(), 'k--')
# k-- 是一个线型选项,表示绘制黑色虚线图
'直接调用AxesSubplot实例化方法可以在其他空格子里面画图'
_ = ax1.hist(randn(100), bins=20, color='k', alpha=0.3)
ax2.scatter(np.arange(30), np.arange(30) + 3 * randn(30))
plt.close('all')
'plt.subplot(): 合成plt.figure() + Figure.add_subplot(),返回fig和axes'
fig, axes = plt.subplots(2, 3)
print(type(fig),type(axes))
'fig是一个Figure对象'
fig
'axes是一个包含以创建的subplot对象的Numpy数组:可以对axes进行索引'
axes
axes[0,1]
表8-1:pyplot.subplots的选项¶
nrows subplot的行数
ncols subplot的列数
sharex 所有subplot应该使用相同的X轴刻度(调节xlim将会影响所有subplot)
sharey 所有subplot应该使用相同的Y轴刻度(调节ylim将会影响所有subplot)
subplot_kw 用于创建各subplot的关键字字典
**fig_kw 创建figure时的其他关键字,如plt.subplots(2,2,figsize=(8,6))
调整subplots周围的间距¶
'plt.subplots_adjust(): 调整subplot之间以及subplot与外围之间的间距'
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(randn(500), bins=50, color='k', alpha=0.5)
plt.subplots_adjust(wspace=0, hspace=0) #subplot之间间距为0
颜色,标记和线型¶
fig = plt.figure()
'50,10是一组坐标,‘g--’是表示颜色和线型的字符串'
plt.plot(50,10,'g--')
'更明确的做法:与上式等价'
plt.plot(50,25,linestyle='--',color='g')
'标记也可以放在格式字符串中,但是标记类型 o 和线型 -- 必须放在颜色 k 后面'
'标记 marker="o",强调真实数据点,图中虚线为线型的差值'
plt.plot(randn(30).cumsum(), 'ko--')
'更明确的形式:'
plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')
plt.close('all')
data = randn(30).cumsum()
plt.plot(data, 'k--', label='Default')
'drawstyle=: 设置非实际数据点的差值方式'
plt.plot(data, 'k-', drawstyle='steps-post', label='steps-post')
'plt.legend() : 设置图例'
plt.legend(loc='best')
刻度,标签和图例¶
Ticks, labels, and legends
设置标题,轴标签,刻度以及刻度标签¶
Setting the title, axis labels, ticks, and ticklabels
Z对于大多数的图标装饰,主要有两种实现方式:
一:使用过程型的pyplot接口(matlab用户非常熟悉),其目的是交互式使用
如xlim, xticks, 和xticklabels等等之类的方法,分别控制图标的范围、刻度位置、刻度标签
用法:调用时不带参数,xlim() 等价于方法二的 ax.get_xlim()
调用时带参数, xlim(50,100) 等价于方法二的 ax.get_xlim(50, 100)
二:更为面向对象的原生matplotlib API
这里主要使用的是第二种方法
fig = plt.figure(); ax = fig.add_subplot(1, 1, 1)
ax.plot(randn(1000).cumsum())
'ax.set_xticks():设置x轴刻度位置'
'ax.set_xticklabels(): 设置x轴刻度标签'
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(): 设置标题'
ax.set_title('My first matplotlib plot')
'ax.set_xlabel(): 设置x轴标签'
ax.set_xlabel('Stages')
'对Y轴修改类似; '
添加图例¶
Adding legends
'label=: 添加图例'
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") 或 plt.legend(loc="best") 来自动创建图例'
#ax.legend(loc='best')
plt.legend(loc="best")
'loc说明图例存放的位置,一般 ‘best’ 就可以'
plt.close('all')
注解以及在Subplot上绘图¶
Annotations and drawing on a subplot
注解可以通过text, arrow, 和 annotate等函数进行添加。
from datetime import datetime
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
data = pd.read_csv('ch08/spx.csv', index_col=0, parse_dates=True)
spx = data['SPX']
spx.plot(ax=ax, style='k-')
crisis_data = [
(datetime(2007, 10, 11), 'Peak of bull market'),
(datetime(2008, 3, 12), 'Bear Stearns Fails'),
(datetime(2008, 9, 15), 'Lehman Bankruptcy')
]
for date, label in crisis_data:
ax.annotate(label, xy=(date, spx.asof(date) + 50),
xytext=(date, spx.asof(date) + 200),
arrowprops=dict(facecolor='black'),
horizontalalignment='left', verticalalignment='top')
# Zoom in on 2007-2010
ax.set_xlim(['1/1/2007', '1/1/2011'])
ax.set_ylim([600, 1800])
ax.set_title('Important dates in 2008-2009 financial crisis')
plt.close('all')
图形的绘制要麻烦一些,matplotlib有一些表示常见图形的对象。这些对象被称为块(patch)。其中有些可以在matplotlib.pyplot中找到
如(Rectangle和Circle),但完整的集合位于matplotlib.patches。
要在图标中添加一个图形,你需要创建一个块对象shp, 然后通过ax.add_patch(shp)将其添加到subplot中
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)
将图表保存到文件¶
fig
'ax 不是 fig'
ax
'plt.savefig():将当前图标保存到文件,也可以用实例化方法 fig.savefig()'
fig.savefig('figpath.svg')
'文件保存的类型通过扩展名推断出来: .png表示保存到图片'
'fig.savefig()常用参数:dpi= : 控制‘每英寸点数’分辨率 和 bbox_inches= (可以剪除当前图标周围的空白部分)'
fig.savefig('figpath.png', dpi=400, bbox_inches='tight')
'得到一张带有最小白边且分表率为 400DPI的图片'
'savefig也可以写入任何文件类型的对象'
from io import BytesIO
buffer = BytesIO()
plt.savefig(buffer)
plot_data = buffer.getvalue()
'注意:这部分不会使用。。'
表8-2:Figure.savefig的选项¶
fname 含有文件路径的字符串或Python的文件型对象。图像格式由文件扩展名推断得出,例如,.pdf推断出PDF,.png推断出PNG
dpi 图像分辨率(每英寸点数),默认为100
facecolor,edgecolor 图像的背景色,默认为‘w’(白色)
format 显式设置文件格式('png','pdf','svg','ps','eps'......)
bbox_inches 图表需要保存的部分。如果设置为‘tight’,则将尝试剪除图表周围的空白部分
matplotlib 配置¶
'rc方法是对matplotlib进行全局默认设置,具体见参考书'
plt.rc('figure', figsize=(10, 5))
plt.plot()
pandas中的绘图函数¶
线形图¶
plt.close('all')
'Series的plot方法默认是绘制线性图像'
s = Series(np.random.randn(10).cumsum(), index=np.arange(0, 100, 10))
s.plot()
'DateFrame的plot方法会在一个subplot中为各列绘制一条线,并自动创建图例'
df = DataFrame(np.random.randn(10, 4).cumsum(0),
columns=['A', 'B', 'C', 'D'],
index=np.arange(0, 100, 10))
df.plot()
表8-3:Series.plot方法的参数¶
label 用于图里的标签
ax 要在其上进行绘制的matplotlib subplot对象。如果没有设置,则使用当前matplotlib subplot
style 将要传给matplotlib的风格字符串(如'ko--')
alpha 图表的填充不透明度(0到1之间)
kind 可以是'line','bar','barh','kde'
logy 在Y轴上使用对数标尺
use_index 将对象的索引用作刻度标签
rot 旋转刻度标签(0到360)
xticks 用作X轴刻度的值
yticks 用作Y轴刻度的值
xlim X轴的界限(例如[0,10])
ylim Y轴的界限
grid 显示轴网格线(默认打开)
表8-4:专用于DataFrame的plot参数:¶
subplots 将各个DataFrame列绘制到单独的subplot中
sharex 如果subplot=True,则共用同一个X轴,包括刻度和界限
sharey 如果subplot=True,则共用同一个Y轴,包括刻度和界限
figsize 表示图像大小的元组
title 表示图像标题的字符串
legend 添加一个subplot图例(默认为True)
sort_columns 以字母表顺序绘制各列,默认使用当前列顺序
柱状图¶
'柱状图:kind="bar"(bar是垂直柱状图,barh是水平柱状图),默认把索引作为X(bar)或Y(barh)刻度'
fig, axes = plt.subplots(2, 1)
data = Series(np.random.rand(16), index=list('abcdefghijklmnop'))
data.plot(kind='bar', ax=axes[0], color='k', alpha=0.7)
data.plot(kind='barh', ax=axes[1], color='k', alpha=0.7)
'各列的名称 name="Genus" 被用做了图例的标题'
df = 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(kind='bar')
'柱状图的一个不错的用法:利用value_counts图形化显示Series中各值出现的频率'
test = Series(np.random.randint(1,10,20),index=(range(1,21)))
test.value_counts().plot(kind='bar')
'stacked=: 为Dataframe生成堆积柱状图'
df.plot(kind='barh', stacked=True, alpha=0.5)
tips = pd.read_csv('ch08/tips.csv')
tips.head()
'pd.crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None, margins=False, dropna=True)'
'计算两个元素的简单的交叉表 cross-tabulation'
party_counts = pd.crosstab(tips.day, tips['size'])
party_counts
'1个人和6个人的聚会都比较少'
party_counts = party_counts.ix[:, 2:5]
party_counts.sum(axis=1).astype(float)
# 规范化成 和为1
party_pcts = party_counts.div(party_counts.sum(axis=1).astype(float), axis=0)
party_pcts
party_pcts.plot(kind='bar', stacked=True)
直方图和密度图¶
'hist方法:注意这里不是参数 kind=‘hist’'
tips['tip_pct'] = tips['tip'] / tips['total_bill']
tips['tip_pct'].hist(bins=50) #bins 箱子
'kind="kde",密度图'
tips['tip_pct'].plot(kind='kde')
fig = plt.figure()
'先画直方图'
comp1 = np.random.normal(0, 1, size=200) # N(0, 1)
comp2 = np.random.normal(10, 2, size=200) # N(10, 4)
values = Series(np.concatenate([comp1, comp2])) #合并comp1,comp2,默认axis=0方向合并
values.hist(bins=100, alpha=0.3, color='k', normed=True) #normed=True 标准化 sum(values) 为 1
'再画密度图'
values.plot(kind='kde', style='k--')
散布图¶
Scatter plots
macro = pd.read_csv('ch08/macrodata.csv')
data = macro[['cpi', 'm1', 'tbilrate', 'unemp']]
trans_data = np.log(data).diff().dropna()
trans_data[-5:]
'plt.scatter: 散布图,注意:这个是plt的方法,不是pd的方法'
plt.scatter(trans_data['m1'], trans_data['unemp'])
plt.title('Changes in log %s vs. log %s' % ('m1', 'unemp'))
'pd.scatter_matrix: pd的散步矩阵, diagonal= 参数可以指定在对角线上放置的图像是直方图还是密度图'
pd.scatter_matrix(trans_data, diagonal='kde', color='k', alpha=0.3)
绘制地图:图形化显式海地地震危机数据(略)¶
Plotting Maps: Visualizing Haiti Earthquake Crisis data
data = pd.read_csv('ch08/Haiti.csv')
data.info()
data[['INCIDENT DATE', 'LATITUDE', 'LONGITUDE']][:10]
data['CATEGORY'][:6]
data.describe()
data = data[(data.LATITUDE > 18) & (data.LATITUDE < 20) &
(data.LONGITUDE > -75) & (data.LONGITUDE < -70)
& data.CATEGORY.notnull()]
def to_cat_list(catstr):
stripped = (x.strip() for x in catstr.split(','))
return [x for x in stripped if x]
def get_all_categories(cat_series):
cat_sets = (set(to_cat_list(x)) for x in cat_series)
return sorted(set.union(*cat_sets))
def get_english(cat):
code, names = cat.split('.')
if '|' in names:
names = names.split(' | ')[1]
return code, names.strip()
get_english('2. Urgences logistiques | Vital Lines')
all_cats = get_all_categories(data.CATEGORY)
# Generator expression
english_mapping = dict(get_english(x) for x in all_cats)
english_mapping['2a']
english_mapping['6c']
def get_code(seq):
return [x.split('.')[0] for x in seq if x]
all_codes = get_code(all_cats)
code_index = pd.Index(np.unique(all_codes))
dummy_frame = DataFrame(np.zeros((len(data), len(code_index))),
index=data.index, columns=code_index)
dummy_frame.ix[:, :6].info()
for row, cat in zip(data.index, data.CATEGORY):
codes = get_code(to_cat_list(cat))
dummy_frame.ix[row, codes] = 1
data = data.join(dummy_frame.add_prefix('category_'))
data.ix[:, 10:15].info()
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
def basic_haiti_map(ax=None, lllat=17.25, urlat=20.25,
lllon=-75, urlon=-71):
# create polar stereographic Basemap instance.
m = Basemap(ax=ax, projection='stere',
lon_0=(urlon + lllon) / 2,
lat_0=(urlat + lllat) / 2,
llcrnrlat=lllat, urcrnrlat=urlat,
llcrnrlon=lllon, urcrnrlon=urlon,
resolution='f')
# draw coastlines, state and country boundaries, edge of map.
m.drawcoastlines()
m.drawstates()
m.drawcountries()
return m
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 10))
fig.subplots_adjust(hspace=0.05, wspace=0.05)
to_plot = ['2a', '1', '3c', '7a']
lllat=17.25; urlat=20.25; lllon=-75; urlon=-71
for code, ax in zip(to_plot, axes.flat):
m = basic_haiti_map(ax, lllat=lllat, urlat=urlat,
lllon=lllon, urlon=urlon)
cat_data = data[data['category_%s' % code] == 1]
# compute map proj coordinates.
x, y = m(cat_data.LONGITUDE.values, cat_data.LATITUDE.values)
m.plot(x, y, 'k.', alpha=0.5)
ax.set_title('%s: %s' % (code, english_mapping[code]))
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 10))
fig.subplots_adjust(hspace=0.05, wspace=0.05)
to_plot = ['2a', '1', '3c', '7a']
lllat=17.25; urlat=20.25; lllon=-75; urlon=-71
def make_plot():
for i, code in enumerate(to_plot):
cat_data = data[data['category_%s' % code] == 1]
lons, lats = cat_data.LONGITUDE, cat_data.LATITUDE
ax = axes.flat[i]
m = basic_haiti_map(ax, lllat=lllat, urlat=urlat,
lllon=lllon, urlon=urlon)
# compute map proj coordinates.
x, y = m(lons.values, lats.values)
m.plot(x, y, 'k.', alpha=0.5)
ax.set_title('%s: %s' % (code, english_mapping[code]))
make_plot()
shapefile_path = 'ch08/PortAuPrince_Roads/PortAuPrince_Roads'
m.readshapefile(shapefile_path, 'roads')

浙公网安备 33010602011771号