频次直方图、KDE和密度图

本文介绍了Seaborn库在数据可视化中的应用,包括频次直方图、KDE、矩阵图、分面直方图和不同类型的图表,以及如何使用Basemap进行地图绘制,展示了如何在地图上展示数据和使用各种地图投影。
摘要由CSDN通过智能技术生成

Seaborn的主要思想是用高级命令为统计数据探索和统计模型拟合创建各种图形,下面将介绍一些Seaborn中的数据集和图形类型。

虽然所有这些图形都可以用Matplotlib命令实现(其实Matplotlib就是Seaborn的底层),但是用 Seaborn API会更方便。

频次直方图、KDE和密度图

在进行统计数据可视化时,我们通常想要的就是频次直方图和多变量的联合分布图。在Matplotlib里面我们已经见过,相对比较简单:

 
  1. data = np.random.multivariate_normal([0, 0], [[5, 2], [2, 2]], size=2000)
  2. data = pd.DataFrame(data, columns=['x', 'y'])
  3. for col in 'xy':
  4. plt.hist(data[col], normed=True, alpha=0.5)

除了频次直方图,我们还可以用KDE获取变量分布的平滑估计。在seaborn通过sns.kdeplot来实现:

 
  1. for col in 'xy':
  2. sns.kdeplot(data[col], shade=True)

使用distplot可以将频次直方图和KDE结合起来:

 
  1. sns.distplot(data['x'])
  2. sns.distplot(data['y'])

如果向kdeplot输入的是二维数据集,那么就可以获得一个二维数据可视化图:sns.kdeplot(data)

矩阵图

当我们需要对多维数据进行可视化是,最终都要使用矩阵图,矩阵图对于探索多维数据不同维度间的相关性非常有效。

下面将用鸢尾花数据集来演示,其中有三种鸢尾花的花瓣与花萼数据:

 
  1. data = pd.read_csv("iris.csv")
  2. sns.pairplot(data,hue="species") #hue 选择分类列

分面频次直方图

有时观察数据最好的方法就是借助数据子集的频次直方图,SeabornFacetGrid函数让这件事变得非常简单。

来看看某个餐厅统计的服务员收取小费的数据:

 
  1. tips = pd.read_csv('tips.csv')
  2. g = sns.FacetGrid(tips, col="time", row="smoker")
  3. g = g.map(plt.hist, "total_bill", color="r")

条形图

对于时间序列数据可以使用sns.factorplot画出条形图,下面将使用行星数据来演示:

 
  1. planets = pd.read_csv('planets.csv')
  2. with sns.axes_style('white'):
  3. g = sns.factorplot("year", data=planets, aspect=2,
  4. kind="count", color='steelblue')
  5. g.set_xticklabels(step=5)

还可以对用不同方法发现行星的数量:

 
  1. with sns.axes_style('white'):
  2. g = sns.factorplot("year", data=planets, aspect=4.0, kind='count',
  3. hue='method', order=range(2001, 2015))
  4. g.set_ylabels('Number of Planets Discovered')

折线图

seaborn绘制折线图使用lineplot函数,该函数所传数据必须为一个pandas数组,这一点跟matplotlib里有较大的区别,并且一开始使用较为复杂。

首先sns.lineplot里有几个参数值得注意:

  • x:plot图的xlabel

  • y:plot图的ylabel

  • ci:与估计器聚合时绘制的置信区间的大小;

  • data: 所传入的pandas数组。

 
  1. x = np.linspace(100, 50, 6)
  2. y = np.array([0.194173876, 0.161086478, 0.138896531, 0.129826697, 0.133716787, 0.152458326])
  3. summary = []
  4. for i in range(6):
  5. x_t = x[i]
  6. y_t = y[i]
  7. summary.append([x_t, y_t])
  8. data =pd.DataFrame(summary )
  9. sns.lineplot(x=0,y=1,ci=None,data=data)

编程要求

BasemapMatplotlib的一个子包,负责地图绘制。在数据可视化过程中,我们常需要将数据在地图上画出来。

比如说我们在地图上画出城市人口,飞机航线,军事基地,矿藏分布等等。这样的地理绘图有助于读者理解空间相关的信息。

  • 适用场景:适用于有空间位置的数据集。

安装和使用

相对于其他工具Basemap用起来有点笨重,就算做点儿简单的可视化图也需要花费比预期更长的时间。

在处理比较复杂的地图可视化任务时,更现代的解决方案可能会更适用一些,比如leafletGoogle Maps API。然而,Basemap 符合Python用户的使用习惯。

basemap并没有集成到matplotlib中,需要我们手动安装,basemap安装起来很简单,这里就不在说明。

安装并导入basemap工具箱后,只需要用几行代码就可以画出地理图:

 
  1. import matplotlib.pyplot as plt
  2. from mpl_toolkits.basemap import Basemap#导入工具包
  3. plt.figure(figsize=(8, 8))
  4. m = Basemap(projection='ortho', resolution=None, lat_0=50, lon_0=-100)
  5. m.bluemarble(scale=0.5)
  6. plt.show()

运用Basemap函数我们可以在绘图区域中绘制地理信息相关的图像,当参数 projection的值为'ortho'时,我们将得到一个如上图所示的地球仪截面。 将参数projection的值设置为lcc时,我们可以通过经纬度设置来得到某一区域的局部地图:

 
  1. fig = plt.figure(figsize=(8, 8))
  2. m = Basemap(projection='lcc', resolution=None,width=8E6,height=8E6,lat_0=45, lon_0=-100,)m.etopo(scale=0.5, alpha=0.5)
  3. # 将经纬度映射为 (x, y) 坐标,用于绘制图像
  4. x, y = m(-122.3, 47.6)
  5. plt.plot(x, y, 'ok', markersize=5)
  6. plt.text(x, y, ' Seattle', fontsize=12)

这里使用了两个额外参数,它们用来表示地图中心的纬度(lat_0)和经度( lon_0)。

地图投影

由于不可能把地表完美反映到二维平面上,所有的地图都是各种各样扭曲的产物,把这些扭曲的产物抹平到平面坐标系的过程,称为投影。

Basemap提供了几十种不同的投影的实现。

投影简写-全称对照:

简写全称
cylCylindrical Equidistant
mercMercator
tmercTransverse Mercator
omercOblique Mercator
millMiller Cylindrical
gallGall Stereographic Cylindrical
ceaCylindrical Equal Area
lccLambert Conformal
laeaLambert Azimuthal Equal Area
nplaeaNorth-Polar Lambert Azimuthal
splaeaSouth-Polar Lambert Azimuthal
eqdcEquidistant Conic
aeqdAzimuthal Equidistant
npaeqdNorth-Polar Azimuthal Equidistant
spaeqdSouth-Polar Azimuthal Equidistant
aeaAlbers Equal Area
stereStereographic
npstereNorth-Polar Stereographic
spstereSouth-Polar Stereographic
cassCassini-Soldner
polyPolyconic
orthoOrthographic
geosGeostationary
nsperNear-Sided Perspective
sinuSinusoidal
mollMollweide
hammerHammer
robinRobinson
kav7Kavrayskiy VII
eck4Eckert IV
vandgvan der Grinten
mbtfpqMcBryde-Thomas Flat-Polar Quartic
gnomGnomonic
rotpoleRotated Pole

下面我们对一常用的投影进行简单的演示。定义一个可以画带经纬线地图的简便方法:

 
  1. def draw_map(m, scale=0.2):
  2. # 画地貌晕渲图
  3. m.shadedrelief(scale=scale)
  4. # 用字典表示经纬度
  5. lats = m.drawparallels(np.linspace(-90, 90, 13))
  6. lons = m.drawmeridians(np.linspace(-180, 180, 13))
  7. # 字典的键是plt.Line2D示例
  8. lat_lines = chain(*(tup[1][0] for tup in lats.items()))
  9. lon_lines = chain(*(tup[1][0] for tup in lons.items()))
  10. all_lines = chain(lat_lines, lon_lines)
  11. # 用循环将所有线设置成需要的样式
  12. for line in all_lines:
  13. line.set(linestyle='-', alpha=0.3, color='w')

圆柱投影是最简单的地图投影类型,纬度线与经度线分别映射成水平线与竖直线。 采用这种投影类型的话,赤道区域的显示效果非常好,但是南北极附近的区域就会严重变形。

 
  1. fig = plt.figure(figsize=(8, 6), edgecolor='w')
  2. m = Basemap(projection='cyl', resolution=None,
  3. llcrnrlat=-90, urcrnrlat=90,
  4. llcrnrlon=-180, urcrnrlon=180, )
  5. draw_map(m)

这里basemap参数设置了左下角(llcrnr)和右上角(urcrnr)纬度(lat)和经度(lon)。不同的投影都有各种的优劣,大家之后可以多多尝试。

地图背景

basemap程序包中有许多实用的函数,可以画出各种地形的轮廓,如陆地、海洋、湖泊、河流、各国的政治分界线。

常用画图函数:

函数说明
drawcoastlines()绘制大陆海岸线
drawlsmask()为陆地与海洋设置填充色,从而可以在陆地或海洋投影其他图像
drawmapboundary()绘制地图边界,包括为海洋填充颜色
drawrivers()绘制河流
fillcontinents()用一种颜色填充大陆,用另一种颜色填充湖泊(可选)
drawcountries()绘制国界线
drawstates()绘制美国州界线
drawcounties()绘制美国县界线
drawgreatcircle()在两点之间绘制一个大圆
drawparallels()绘制纬线
drawmeridians()绘制经线
drawmapscale()在地图上绘制一个线性比例尺
bluemarble()绘制NASA 蓝色弹珠地球投影
shadedrelief()在地图上绘制地貌晕渲图
etopo()在地图上绘制地形晕渲图
warpimage()将用户提供的图像投影到地图上

如果要使用边界特征,就必须设置分辨率。通过resolution来设置分辨率,取值为c(原始分辨率)、l(低分辨率)、i(中分辨率)、h(高分辨率)、f(全画质分辨率)。

来看看两种不同分辨率的绘制效果:

 
  1. fig, ax = plt.subplots(1, 2, figsize=(12, 8))
  2. for i, res in enumerate(['l', 'h']):
  3. m = Basemap(projection='gnom', lat_0=57.3, lon_0=-6.2,
  4. width=90000, height=120000, resolution=res, ax=ax[i])
  5. m.fillcontinents(color="#FFDDCC", lake_color='#DDEEFF')
  6. m.drawmapboundary(fill_color="#DDEEFF")
  7. m.drawcoastlines()
  8. ax[i].set_title("resolution='{0}'".format(res));
  9. plt.show()

可以看出低分辨率不适合这个缩放,低分辨率适合呈现全局视角,而且加载速度比高分辨率更快。要呈现某一视角的适合,最好先从一个能快速呈现的分辨率开始,然后不断提高分辨率直到满意为止。

在地图上画数据

basemap还可以以地图为背景,在这上面画各种数据。basemap实例中许多方法都是与地图有关的函数。这些函数与标准matplotlib函数的用法类似,只是多了一个参数latlon。如果设置为true表示使用原来的经纬度坐标,不使用投影(x,y)坐标。

示例如下:

 
  1. import pandas as pd
  2. cities = pd.read_csv('california_cities.csv')
  3. # 提取我们感兴趣的数据
  4. lat = cities['latd'].values
  5. lon = cities['longd'].values
  6. population = cities['population_total'].values
  7. area = cities['area_total_km2'].values
  8. # 1. 绘制地图背景
  9. fig = plt.figure(figsize=(8, 8))
  10. m = Basemap(projection='lcc', resolution='h',
  11. lat_0=37.5, lon_0=-119,
  12. width=1E6, height=1.2E6)
  13. m.shadedrelief()
  14. m.drawcoastlines(color='gray')
  15. m.drawcountries(color='gray')
  16. m.drawstates(color='gray')
  17. # 2. 绘制城市数据的散点图,其中颜色反映人口
  18. # 尺寸反映面积
  19. m.scatter(lon, lat, latlon=True,
  20. c=np.log10(population), s=area,
  21. cmap='Reds', alpha=0.5)
  22. # 3. 创建颜色条和图例
  23. plt.colorbar(label=r'$\log_{10}({\rm population})$')
  24. plt.clim(3, 7)
  25. # 使用虚拟的点生成图例
  26. for a in [100, 300, 500]:
  27. plt.scatter([], [], c='k', alpha=0.5, s=a,
  28. label=str(a) + ' km$^2$')
  29. plt.legend(scatterpoints=1, frameon=False,
  30. labelspacing=1, loc='lower left');

编程要求

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值