系列文章:Python 数据分析
import matplotlib.pyplot as plt
matplotlib的图像都位于Figure对象中。创建一个新Figure:
fig = plt.figure()
不能通过空Figure绘图。必须用add_subplot创建一个或多个subplot才行:
# 图像是2*2的
ax1 = fig.add_subplot(2, 2, 1) # 选中第一张图
ax2 = fig.add_subplot(2, 2, 2) # 选中第二张图
ax3 = fig.add_subplot(2, 2, 3) # 选中第三张图
默认情况下,matplotlib会在subplot外围留下一定的边距,并在subplot之间留下一定的间距。间距跟图像的高度和宽度有关。
subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
matplotlib的plot函数接受一组X和Y坐标,还可以接受一个表示颜色和线型的字符串缩写。
ax.plot(x, y, 'g--')
ax.plot(x, y, linestyle='--', color='g')
常用的颜色可以使用颜色缩写,你也可以指定颜色码(例如,’#CECECE’)。
线图可以使用标记强调数据点。标记类型和线型必须放在颜色后面。
from numpy.random import randn
plt.plot(randn(30).cumsum(), 'ko--')
# 或者
plot(randn(30).cumsum(), color='k', linestyle='dashed', marker='o')
xlim、xticks和xticklabels 分别控制图表的范围、刻度位置、刻度标签。
调用时不带参数,则返回当前的参数值(例如,plt.xlim()返回当前的X轴绘图
范围)。调用时带参数,则设置参数值(例如,plt.xlim([0,10])会将X轴的范围设置为0到10)。
它们分别对应subplot对象上的两个方法,比如 xlim 对应 ax.get_xlim 和 ax.set_xlim。
不同的线要有不同的 lable,也就是这里的图例。
最简单的是在添加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')
注解和文字可以通过text、arrow和annotate函数进行添加。
ax.text(x, y, 'Hello world!', family='monospace', fontsize=10)
注解中可以既含有文本也含有箭头。
要在图表中添加一个图形,你需要创建一个块对象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)
利用plt.savefig可以将当前图表保存到文件:
plt.savefig('figpath.svg')
两个重要的选项是dpi(控制“每英寸点数”分辨率)和bbox_inches(可以剪除当前图表周围的空白部分):
# 最小白边且分辨率为400DPI的PNG图片
plt.savefig('figpath.png', dpi=400, bbox_inches='tight')
savefig并非一定要写入磁盘,也可以写入任何文件型的对象,比如BytesIO:
from io import BytesIO
buffer = BytesIO()
plt.savefig(buffer)
plot_data = buffer.getvalue()
在pandas中,我们有多列数据,还有行和列标签。pandas自身就有内置的方法,用于简化从DataFrame和Series绘制图形。
另一个库seaborn(https://seaborn.pydata.org/),由Michael Waskom创建的静态图形库。Seaborn简化了许多常见可视类型的创建。
Series 和 DataFrame 都有一个用于生成各类图表的plot方法。默认情况下,它们所生成的是线型图:
s = pd.Series(np.random.randn(10).cumsum(), index=np.arange(0, 100, 10))
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()
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) # 索引为x刻度
data.plot.barh(ax=axes[1], color='k', alpha=0.7) # 索引为y刻度
对于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.plot.bar()
直方图 plot.hist方法
密度图 plot.density方法
seaborn 的 distplot 方法绘制直方图和密度图更加简单,还可以同时画出直方图和连续密度估计图:
comp1 = np.random.normal(0, 1, size=200)
comp2 = np.random.normal(10, 2, size=200)
values = pd.Series(np.concatenate([comp1, comp2]))
sns.distplot(values, bins=100, color='k')
使用seaborn的regplot方法,它可以做一个散布图,并加上一条线性回归的线:
import seaborn as sns
sns.regplot('m1', 'unemp', data=your_data)
在探索式数据分析工作中,同时观察一组变量的散布图是很有意义的,这也被称为散布图矩阵(scatter plot matrix)。
seaborn提供了一个便捷的pairplot函数,它支持在对角线上放置每个变量的直方图或密度估计:
sns.pairplot(trans_data, diag_kind='kde', plot_kws={'alpha': 0.2})
一个数据有多个分类维度的情况。
有多个分类变量的数据可视化的一种方法是使用小面网格。seaborn有一个有用的内置函数factorplot,可以简化制作多种分面图:
sns.factorplot(x='day', y='tip_pct', hue='time', col='smoker',kind='bar', data=tips[tips.tip_pct < 1])