DataJam

二、关联图之气泡图

1. 变散点为气泡

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

midwest = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/midwest_filter.csv")
 1 #plt.style.use('seaborn-whitegrid')
 2 #sns.set_style("white")
 3 
 4 #预设图像的各种属性
 5 large = 22; med = 16; small = 12
 6 params = {'axes.titlesize': large, #子图上的标题字体大小
 7           'legend.fontsize': med, #图例的字体大小
 8           'figure.figsize': (16, 10), #图像的画布大小
 9           'axes.labelsize': med, #标签的字体大小
10           'xtick.labelsize': med, #x轴上的标尺的字体大小
11           'ytick.labelsize': med, #y轴上的标尺的字体大小
12           'figure.titlesize': large} #整个画布的标题字体大小
13 plt.rcParams.update(params) #设定各种各样的默认属性
14 #plt.style.use('seaborn-whitegrid') #设定整体风格
15 #sns.set_style("white") #设定整体背景风格
16 
17 %matplotlib inline
18 
19 #准备标签列表
20 categories = np.unique(midwest['category'])
21 colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
22 
23 #布置画布
24 fig = plt.figure(figsize=(14,8), dpi=120, facecolor='w', edgecolor='k')    
25 
26 #循环绘图
27 #之前在给散点加入颜色的时候,我们提到X轴,Y轴上的值和我们的颜色是一一对应的
28 #那只要点的尺寸和我们的坐标点(x1,x2)一一对应,那我们就可以相应地给每一个点添加尺寸信息
29 for i, category in enumerate(categories):
30     plt.scatter('area', 'poptotal', data=midwest.loc[midwest.category==category, :]
31                 #, s = midwest.loc[midwest.category==category, "percasian"]*500 #调整尺寸,让散点图成为气泡图
32                 , s = "popasian" #现在的特征为我们的点的尺寸大小
33                 #, s=20 #size
34                 , c= np.array(colors[i]).reshape(1,-1)
35                 , label=str(category)
36                 , edgecolors = np.array(colors[i]).reshape(1,-1) #点的边缘的颜色
37                 #, edgecolors="k"
38                 , alpha = 0.7 #图像的透明度
39                 , linewidths=0.5 #点的外圈的线条的宽度
40                )
41 
42 #装饰图像
43 plt.gca().set(xlim=(0.0, 0.12), ylim=(0, 90000),
44               xlabel='Area', ylabel='Population')
45 plt.xticks(fontsize=12)
46 plt.yticks(fontsize=12)
47 plt.title("Bubble Plot with Encircling", fontsize=22)
48 plt.legend(fontsize=12
49            ,markerscale=0.5 #现有的图例气泡的某个比例
50           )
51 plt.show()

 

 

带标签的气泡

 1 #plt.style.use('seaborn-whitegrid')
 2 #sns.set_style("white")
 3 
 4 #预设图像的各种属性
 5 large = 22; med = 16; small = 12
 6 params = {'axes.titlesize': large, #子图上的标题字体大小
 7           'legend.fontsize': med, #图例的字体大小
 8           'figure.figsize': (16, 10), #图像的画布大小
 9           'axes.labelsize': med, #标签的字体大小
10           'xtick.labelsize': med, #x轴上的标尺的字体大小
11           'ytick.labelsize': med, #y轴上的标尺的字体大小
12           'figure.titlesize': large} #整个画布的标题字体大小
13 plt.rcParams.update(params) #设定各种各样的默认属性
14 #plt.style.use('seaborn-whitegrid') #设定整体风格
15 #sns.set_style("white") #设定整体背景风格
16 
17 %matplotlib inline
18 
19 #准备标签列表
20 categories = np.unique(midwest['category'])
21 colors = ["red","orange","pink"]
22 
23 #布置画布
24 fig = plt.figure(figsize=(14,8), dpi=120, facecolor='w', edgecolor='k')    
25 
26 #循环绘图
27 for i, category in enumerate(["AHR","HAU","LHU"]):
28     data_ = midwest.loc[midwest.category==category, :]
29     data_.index = range(data_.shape[0])
30     plt.scatter('area', 'poptotal', data=data_
31                 , s= midwest.loc[midwest.category==category, "poppovertyknown"]*0.05 #调整尺寸,让散点图成为气泡图
32                 , c= colors[i]
33                 , label=str(category)
34                 , edgecolors= colors[i]
35                 , alpha = 0.7
36                 , linewidths=.5
37                )
38     for i in range(midwest.loc[midwest.category==category, :].shape[0]):
39         plt.text(data_.loc[i,"area"]
40                  ,data_.loc[i,"poptotal"]
41                  ,s=data_.loc[i,"county"] #虽然参数都写作s,但这里的s指的是字符串string的s,不是size的s
42                  ,fontdict={"fontsize":8} #调整我们的字符串的字体大小
43                  ,horizontalalignment='right' #相对于我的气泡,把我的字符串显示在哪里
44                 )
45         
46 #装饰图像
47 plt.gca().set(xlim=(0.0, 0.1), ylim=(0, 90000),
48               xlabel='Area', ylabel='Population')
49 plt.xticks(fontsize=12)
50 plt.yticks(fontsize=12)
51 plt.title("Bubble Plot with Encircling", fontsize=22)
52 lgnd = plt.legend(fontsize=12
53                   ,markerscale=0.2
54                  )
55 plt.show()

 

 

2. 将散点框起来

 

什么时候会存在这样的需求呢?来看一组数据:

 

1 import matplotlib.pyplot as plt
2 import numpy as np; np.random.seed(1) #随机模式1号
3 
4 #random.randn 取出符合标准正态分布的随机数
5 #random.normal 取出符合正态分布的随机数
6 x1, y1 = np.random.normal(loc=5 #正态分布中的均值
7                           , scale=2 #正态分布中的方差
8                           , size=(2,15) #生成怎样的数据结构,2列,每列15个数据
9                          )

我们希望能够绘制一个边界,将同一类的点框起来。
在这里我们将用到SciPy库,这是一个专为Python设计的,专注于数学&工程学的库
今天我们将用到SciPy中专门处理空间算法和数据结构的模块:SciPy库中的spatial

 

scipy.spatial.ConvexHull()

 

ConvexHull直译是凸包,表示在一个平面上,我们能找到的最小的将一组数据全部包括在内的凸集
通俗的来说凸包就是包围一组散点的最小凸边形
相对的我们也有凹边形

 
 

ConvexHull能够帮助我们创建N维凸包

重要参数

points:浮点数组成的n维数组,结构为(点的个数,维度)。表示用来构成凸包的坐标点。
incremental:布尔值,可不填。允许不断向类中添加新的数据点。

 

重要属性

vertices:组成凸包的那些数据点在原数据中的索引

*更多参数和属性走:https://docs.scipy.org/doc/scipy-0.19.0/reference/generated/scipy.spatial.ConvexHull.html

 

 1 from scipy.spatial import ConvexHull
 2 from matplotlib import patches
 3 #patches,给现有图像打补丁的包,在现有的图像上增加更多的东西
 4 
 5 #定义绘制凸包的函数
 6 def encircle(x,y, ax=None, **kw):
 7     if not ax: ax=plt.gca() #获取当前子图,如果当前子图不存在,那就创建新的子图(get current ax)
 8     p = np.c_[x,y] #.c_功能类似于zip,不过不是生成组合的元祖,而是生成拼接起来的数组array
 9     hull = ConvexHull(p) #将数据集输入到ConvexHull中,自动生成凸包类型的对象
10     poly = plt.Polygon(p[hull.vertices,:], **kw)
11         #使用属性vertices调用形成凸包的点的索引,进行切片后,利用绘制多边形的类plt.Polygon将形成凸包的点连起来
12         #这里的**kw就是定义函数的时候输入的**kw,里面包含了一系列可以在绘制多边形的类中进行调节的内容
13         #包括多边形的边框颜色,填充颜色,透明度等等
14     ax.add_patch(poly) #使用add_patch,将生成的多边形作为一个补丁补充到图像上
15 
16 
17 plt.scatter(x1, y1)
18 plt.scatter(x2, y2)
19 
20 encircle(x1, y1
21          , ec="k" #线条的颜色
22          , fc="gold" #多边形的颜色
23          , alpha=0.2 #图像整体的透明度
24         )
25 #你是否注意到,边框也是透明的?
26 
27 encircle(x2, y2, ec="orange", fc="none")
28 
29 plt.show()

 

 

完整绘图

 1 from scipy.spatial import ConvexHull
 2 from matplotlib import patches
 3 
 4 plt.style.use('seaborn-whitegrid')
 5 sns.set_style("white")
 6 
 7 #预设图像的各种属性
 8 large = 22; med = 16; small = 12
 9 params = {'axes.titlesize': large, #子图上的标题字体大小
10           'legend.fontsize': med, #图例的字体大小
11           'figure.figsize': (16, 10), #图像的画布大小
12           'axes.labelsize': med, #标签的字体大小
13           'xtick.labelsize': med, #x轴上的标尺的字体大小
14           'ytick.labelsize': med, #y轴上的标尺的字体大小
15           'figure.titlesize': large} #整个画布的标题字体大小
16 plt.rcParams.update(params) #设定各种各样的默认属性
17 plt.style.use('seaborn-whitegrid') #设定整体风格
18 sns.set_style("white") #设定整体背景风格
19 
20 %matplotlib inline
21 
22 #准备标签列表
23 categories = np.unique(midwest['category'])
24 colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
25 
26 #布置画布
27 fig = plt.figure(figsize=(16, 10), dpi=120, facecolor='w', edgecolor='k')    
28 
29 #循环绘图
30 for i, category in enumerate(categories):
31     plt.scatter('area', 'poptotal', data=midwest.loc[midwest.category==category, :]
32                 , s="popasian" #调整尺寸,让散点图成为气泡图
33                 , c= np.array(colors[i]).reshape(1,-1)
34                 , label=str(category)
35                 , edgecolors= np.array(colors[i]).reshape(1,-1)
36                 , alpha = 0.7
37                 , linewidths=.5)
38 
39 #绘制凸包
40 
41 #定义函数
42 def encircle(x,y, ax=None, **kw):
43     if not ax: ax=plt.gca()
44     p = np.c_[x,y]
45     hull = ConvexHull(p)
46     poly = plt.Polygon(p[hull.vertices,:], **kw)
47     ax.add_patch(poly)
48 
49 #定义需要被框起来的数据:所有在IN州中的城市
50 midwest_encircle_data = midwest.loc[midwest.state=='IN', :]                  
51 
52 #使用函数绘制
53 
54 #这里绘制的是金色的面
55 encircle(midwest_encircle_data.area
56          , midwest_encircle_data.poptotal
57          , ec="k"
58          , fc="gold"
59          , alpha=0.1
60         ) 
61 
62 #这里绘制的是浅蓝色的线,而面是透明的
63 encircle(midwest_encircle_data.area
64          , midwest_encircle_data.poptotal
65          , ec="lightblue" #线条颜色
66          , fc="none" #填充颜色
67          , linewidth=1.5 #线宽
68         )
69         
70 #装饰图像
71 plt.gca().set(xlim=(0.0, 0.12), ylim=(0, 90000),
72               xlabel='Area', ylabel='Population')
73 
74 plt.xticks(fontsize=12); plt.yticks(fontsize=12)
75 plt.title("Bubble Plot with Encircling", fontsize=22)
76 plt.legend(markerscale=0.6)
77 plt.show()

 

posted on 2021-06-01 14:48  DataJam  阅读(740)  评论(0编辑  收藏  举报

导航