数据可视化

Numpy
pandas
数据可视化 <<=

本文是对数据可视化的介绍,原来只介绍了matplotlib,书中又增加了pandas与seaborn。
对一个工具性的库,并不需要一板一眼的介绍的组成,这里对它进行重新整理,给出整体印象的同时,更加注重示例;并增加panda的plot,seaborn暂不介绍。

Matplot

概述

关系图
一幅图像(figure)由多个子图像(subplot)组成,每个子图像都是一个坐标系(axes,简写ax),每个坐标系(ax)都有2个坐标轴,坐标轴有自己的刻度(ticks)以及自己代表的量(label),刻度上也可以有自己的标志(ticks-lebel)。
除了坐标轴,最主要是数据的展示,用不同的图形来进行展示,如线性、柱状图、饼图、散点图。多个量时,需要有图例(legend)来表示。有时候在图形上,还有一些标注
整个图像一般会有一个标题(title)

基本图形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1) # 图像是2×2 的,选中其中第一个
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
ax4 = fig.add_subplot(2,2,4)

plt.plot(np.random.randn(50).cumsum(), 'k--') # matplotlib会在最后一个用过的subplot上绘制,这里也就是ax4上。 '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)) # 散点图
ax3.pie([15, 30, 45, 10])

plt.subplots_adjust(wspace=0, hspace=0) # 调整个subplot之间的距离,wspace与hspace用户控制宽度与高度的百分比,可以用作subplot之间的间距。

add_subplot需要一个一个的添加,可以用subplots将fig与subplot都拿出来。

1
fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)                # axes是ax的列表

较完整的线形图

1
2
3
4
5
6
7
8
9
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(np.random.randn(1000).cumsum(), 'k', label='one') # 数据1
ax.plot(np.random.randn(1000).cumsum(), 'k--', label='two') # 数据2
ticks = ax.set_xticks([0, 250, 500, 750, 1000]) # 设置x轴刻度
labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'], rotation=30, fontsize='small') # 刻度的标签,并且设置的倾斜30
ax.set_xlabel('Stages') # x轴的标签
ax.set_title('My first matplotlib plot') # 设置标题
ax.legend(loc='best') # 设置图例

图例的位置:

loc string loc code
‘best’ 0
‘uppder right’ 1
‘upder left’ 2
‘lower left’ 3
‘lower right’ 4
‘right’ 5
‘center left’ 6
‘center right’ 7
‘lower center’ 8
‘upper center’ 9
‘center’ 10
1
2
3
4
5
6
7
8
9
10
11
12
13
# 形状:将形状放在handles中
import matplotlib.patches as mpatches
red_patch = mpatches.Patch(color='red', label='The red data')
plt.legend(handles=[red_patch])
plt.show()


import matplotlib.lines as mlines
import matplotlib.pyplot as plt
blue_line = mlines.Line2D([], [], color='blue', marker='*',
markersize=15, label='Blue stars')
plt.legend(handles=[blue_line])
plt.show()

ps:可以在图形中再增加一些描述的文本(text),或者批注(annotate),这些就不写了。

条状图bar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import numpy as np
import matplotlib.pyplot as plt

n_groups = 5

means_men = (20, 35, 30, 35, 27)
std_men = (2, 3, 4, 1, 2)

means_women = (25, 32, 34, 20, 25)
std_women = (3, 5, 2, 3, 3)

fig, ax = plt.subplots()

index = np.arange(n_groups)
bar_width = 0.35

opacity = 0.4
error_config = {'ecolor': '0.3'}

rects1 = plt.bar(index, means_men,
bar_width,
alpha=opacity,
color='b',
yerr=std_men,
error_kw=error_config,
label='Men')

rects2 = plt.bar(index + bar_width, means_women,
bar_width,
alpha=opacity,
color='r',
yerr=std_women,
error_kw=error_config,
label='Women')

plt.xlabel('Group')
plt.ylabel('Scores')
plt.title('Scores by group and gender')
plt.xticks(index + bar_width, ('A', 'B', 'C', 'D', 'E'))
plt.legend()

plt.tight_layout()
plt.show()

表格table

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import numpy as np
import matplotlib.pyplot as plt

data = [[ 66386, 174296, 75131, 577908, 32015],
[ 58230, 381139, 78045, 99308, 160454],
[ 89135, 80552, 152558, 497981, 603535],
[ 78415, 81858, 150656, 193263, 69638],
[ 139361, 331509, 343164, 781380, 52269]]

columns = ('Freeze', 'Wind', 'Flood', 'Quake', 'Hail')
rows = ['%d year' % x for x in (100, 50, 20, 10, 5)]

values = np.arange(0, 2500, 500)
value_increment = 1000

# Get some pastel shades for the colors
colors = plt.cm.BuPu(np.linspace(0, 0.5, len(columns)))
n_rows = len(data)

index = np.arange(len(columns)) + 0.3
bar_width = 0.4

# Initialize the vertical-offset for the stacked bar chart.
y_offset = np.array([0.0] * len(columns))

# Plot bars and create text labels for the table
cell_text = []
for row in range(n_rows):
plt.bar(index, data[row], bar_width, bottom=y_offset, color=colors[row])
y_offset = y_offset + data[row]
cell_text.append(['%1.1f' % (x/1000.0) for x in y_offset])
# Reverse colors and text labels to display the last value at the top.
colors = colors[::-1]
cell_text.reverse()

# Add a table at the bottom of the axes
the_table = plt.table(cellText=cell_text,
rowLabels=rows,
rowColours=colors,
colLabels=columns,
loc='bottom')

# Adjust layout to make room for the table:
plt.subplots_adjust(left=0.2, bottom=0.2)

plt.ylabel("Loss in ${0}'s".format(value_increment))
plt.yticks(values * value_increment, ['%d' % val for val in values])
plt.xticks([])
plt.title('Loss by Disaster')

plt.show()

图像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

# 注意 matplotlib 默认只支持 PNG 格式的图像
img = mpimg.imread('stinkbug.png')
imgplot = plt.imshow(img)

# 单通道
lum_img = img[:,:,0]
imgplot = plt.imshow(lum_img)

# coloarmap
imgplot = plt.imshow(lum_img)
imgplot.set_cmap('hot')

# 限制范围
plt.hist(lum_img.flatten(), 256, range=(0.0,1.0), fc='k', ec='k')
plt.show() #这样能看出散列的位置

imgplot = plt.imshow(lum_img)
imgplot.set_clim(0.0,0.7) #这样进行显示

# resize操作
from PIL import Image
img = Image.open('stinkbug.png')
rsize = img.resize((img.size[0]/10,img.size[1]/10))
rsizeArr = np.asarray(rsize)
imgplot = plt.imshow(rsizeArr) #这里可以看出imshaow显示的就是array数组

imgplot = plt.imshow(rsizeArr)
imgplot.set_interpolation('nearest') #插值,用于弥补缩小后的图像

pandas

pandas 自身有内置的方法,简化DataFrame与Serices的绘制。这里只做简单的介绍。

  • 折线图

    1
    2
    df = pd.DataFrame(np.random.randn(10, 4).cumsum(0), columns=['A', 'B', 'C', 'D'], index=np.arange(0, 100, 10))
    df.plot()
  • 条形图

    1
    2
    3
    4
    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)
  • DataFrame的条形图

    1
    2
    3
    4
    5
    6
    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.plot.bar()