1 准备工作
matplotlib的通常引入约定是:
import matplotlib.pyplot as plt
在Jupyter中运行%matplotlib notebook,就可以直接显示图像,不需要每次都运行plt.show()。
1.1 figure和subplot
matplotlib的图像都位于Figure对象中。使用plt.figure创建一个新的Figure:
fig = plt.figure()
相当于创建一个空画布,然后我们可以在这个画布上绘图,
需要用add_subplot创建一个或多个subplot:
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))
上述代码表明创建图像应该是2×2的(即最多四张图)。
如果没有指定在哪一个子图进行绘图,默认选择最后一个创建的子图。
"k–"是一个线型选项,用于告诉matplotlib绘制黑色虚线图。
1.2 调整subplot周围的间距
默认情况下,subplot外围会留下一定的边距,并在subplot之间留下一定的间距。间距跟图像的高度和宽度有关,因此,如果你调整了图像大小,间距也会自动调整。利用Figure的subplots_adjust方法可以修改间距:
subplots_adjust(left=None, bottom=None, right=None, top=None,
wspace=None, hspace=None)
wspace和hspace用于控制宽度和高度的百分比,可以用作subplot之间的间距。
示例:
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)
1.3 颜色、标记和线型
matplotlib的plot函数接受一组X和Y坐标,还可以接受一个表示颜色和线型的字符串缩写:
ax.plot(x, y, 'g--')
表示绘制绿色虚线,或者可以使用另一种方式:
ax.plot(x, y, linestyle='--', color='g')
以使用颜色缩写,也可以指定颜色码(例可如,’#CECECE’)。
线图可以使用标记强调数据点,更容易看出真实数据点的位置。
from numpy.random import randn
fig, ax = plt.subplots()
plt.plot(randn(30).cumsum(), 'ko--')
还可以将其写成更为明确的形式:
plt.plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')
非实际数据点默认是按线性方式插值的,可以通过drawstyle选项修改:
#drawstyle修改线型
fig, ax = plt.subplots()
data = np.random.randn(30).cumsum()
plt.plot(data, 'k--', label='Default')
plt.plot(data, 'k-', drawstyle='steps-post', label='steps-post')
plt.legend(loc='best')
必须调用plt.legend(或使用ax.legend,如果引用了轴的话)来创建图例,无论绘图时是否传递label标签选项。
1.4 刻度、标签和图例
要改变x轴刻度,最简单的办法是使用set_xticks和set_xticklabels。前者告诉matplotlib要将刻度放在数据范围中的哪些位置,默认情况下,这些位置也就是刻度标签。但我们可以通过set_xticklabels将任何其他的值用作标签,set_xlabel为X轴设置一个名称,并用set_title设置一个标题
#修改刻度,使用set_xticks和set_xticklabels
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')#rotation选项设定x刻度标签倾斜30度
ax.set_title('My first matplotlib plot')#设置一个标题
ax.set_xlabel('Stages')#为X轴设置一个名称
图例(legend)是另一种用于标识图表元素的重要工具。添加图例的方式有多种。最简单的是在添加subplot的时候传入label参数:
#添加图例(legend)
#最简单的是在添加subplot的时候传入label参数:
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()或plt.legend()来自动创建图例
ax.legend(loc='best')
"best"会选择最不碍事的位置。
1.5 线型图
Series和DataFrame都有一个用于生成各类图表的plot方法。默认情况下,它们所生成的是线型图:
s = pd.Series(np.random.randn(10).cumsum(), index=np.arange(0, 100, 10))
#Series对象的索引会被传给matplotlib,并用以绘制X轴。可以通过use_index=False禁用该功能。
#X轴的刻度和界限可以通过xticks和xlim选项进行调节,Y轴就用yticks和ylim
fig = plt.figure()
s.plot()
#DataFrame的plot方法会在一个subplot中为各列绘制一条线,并自动创建图例
df = pd.DataFrame(np.random.randn(10, 4).cumsum(0),
columns=['A', 'B', 'C', 'D'],
index=np.arange(0, 100, 10))
df.plot()
1.6 柱状图
对于series对象:
#柱状图
#plot.bar()和plot.barh()分别绘制水平和垂直的柱状图,Series和DataFrame的索引将会被用作X(bar)或Y(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)
#color='k'和alpha=0.7设定了图形的颜色为黑色,并使用部分的填充透明度
data.plot.barh(ax=axes[1], color='k', alpha=0.7)
对于DataFrame,柱状图会将每一行的值分为一组,并排显示:
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()#DataFrame各列的名称"Genus"被用作了图例的标题
#设置stacked=True即可为DataFrame生成堆积柱状图,这样每行的值就会被堆积在一起
df.plot.bar(stacked=True, alpha=0.5)
柱状图有一个非常不错的用法:利用value_counts图形化显示Series中各值的出现频率,比如s.value_counts().plot.bar()。
1.7 直方图和密度图
#seaborn的distplot方法绘制直方图和密度图,可以同时画出
import seaborn as sns
comp1 = np.random.normal(0, 1, size=200)
comp2 = np.random.normal(10, 2, size=200)
values = pd.Series(np.concatenate([comp1, comp2]))
fig = plt.figure()
sns.distplot(values, bins=100, color='k')
2 泰坦尼克号数据可视化
#可视化展示泰坦尼克号数据集中男女中生存人数分布情况
sex = data['Survived'].groupby(data['Sex'])
sex = sex.sum()
fig = plt.figure()
sex.plot.bar()
绅士风度,女士优先,存活的女性人数比起男性还是多很多的。
#可视化展示泰坦尼克号数据集中男女中生存人与死亡人数的比例图
res = data.groupby(['Survived', 'Sex'])['Survived'].count()
res
res.unstack().plot.bar()
#可视化展示泰坦尼克号数据集中不同票价的人生存和死亡人数分布情况
res = data.groupby(['Fare'])['Survived'].value_counts().sort_values(ascending=False)
res
fig = plt.figure()
res.plot(grid=True)#绘制带网格背景的图像
注意上面对结果进行了降序排序,如果不排序,就无法凸显数据的一个趋势:
#可视化展示泰坦尼克号数据集中不同仓位等级的人生存和死亡人员的分布情况
res = data.groupby(['Pclass'])['Survived'].value_counts().unstack()
res
res.plot.bar()
#使用seaborn绘制
fig = plt.figure()
sns.countplot(x='Pclass', hue='Survived', data=data)
#可视化展示泰坦尼克号数据集中不同年龄的人生存与死亡人数分布情况
facet = sns.FacetGrid(data, hue="Survived",aspect=3)
facet.map(sns.kdeplot,'Age',shade= True)
facet.set(xlim=(0, data['Age'].max()))
facet.add_legend()
小孩子存活的会多一些,毕竟国家的花朵,再看一下票价跟生存与死亡的分布:
票价低的死亡人数更多,留下了穷人的泪水。
#可视化展示泰坦尼克号数据集中不同仓位等级的人年龄分布情况
fig = plt.figure()
data.Age[data.Pclass==1].plot(kind='kde')
data.Age[data.Pclass==2].plot(kind='kde')
data.Age[data.Pclass==3].plot(kind='kde')
plt.xlabel('age')
plt.legend((1,2,3))
#使用seaborn绘制
fig = plt.figure()
sns.kdeplot(data.Age[data.Pclass==1])
sns.kdeplot(data.Age[data.Pclass==2])
sns.kdeplot(data.Age[data.Pclass==3])
plt.xlabel('age')
plt.legend((1,2,3))
看一下兄弟姐妹个数跟生存人数的分布:
有家人存活率还是会高点。
总结
可视化可直观地理解数据要表达的东西。