这篇文章主要介绍“Python怎么实现数据可视化分析38个城市的居住自由指数”,在日常操作中,相信很多人在Python怎么实现数据可视化分析38个城市的居住自由指数问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python怎么实现数据可视化分析38个城市的居住自由指数”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
而在这个报告中有几张数据可视化作品还是比较可圈可点的,作为(在模仿中精进数据可视化)系列文章的开篇之作,我将基于我观察原始数据可视化作品进而构思出的方式,以纯Python的方式模仿复刻。
2.1 观察原作品
其实原作品咋一看上去有点复杂,但经过观察,将原始图片主要元素拆分成几个部分来构思复现方式,还是不算复杂的,我总结为以下几部分:
「1 坐标系部分」
稍微懂点数据可视化的人应该都可以看出原作品的坐标不是常规的笛卡尔坐标系,而是极坐标系,这里复现原作品极坐标系的难点在于,其并不是完整的极坐标系,即左边略小于半圆的区域是隐藏了参考线的。
因此与其在matplotlib中极坐标系的基础上想方法隐藏部分参考线,不如逆向思维,从构造参考线的角度出发,自己组织构造参考线,会更加的自由和灵活。
「2 颜色填充」
这里的「颜色填充」指的是以居住自由指数折线为中线,在购房自由指数折线与租房自由指数折线之间的颜色填充区域,但困难的是这里当购房自由指数高于租房自由指数时对应的颜色为浅蓝绿色,而反过来则变为灰色,与购房自由指数、租房自由指数的颜色相呼应。
我们只需要设定中心点参数在南极点或北极点,再配合简单的经纬度相关知识就可以伪造出任意的经纬线,再利用geopandas中的投影变换向设定好的「正射投影」进行转换,再作为平面坐标进行绘图即可。
譬如按照这个思路来创建东经10度到东经220度之间,以及南纬-90度到-80度之间,对应的5条纬度线和对应38个城市的经线:
import geopandas as gpd from shapely.geometry import LineString, Point, Polygon import matplotlib.pyplot as plt import numpy as np import warnings plt.rcParams['font.sans-serif'] = ['SimHei'] # 解决matplotlib中文乱码问题 plt.rcParams['axes.unicode_minus'] = False # 解决matplotlib负号显示问题 warnings.filterwarnings('ignore') # 设置中心点在南极点的正射投影 crs = '+proj=ortho +lon_0=0 +lat_0=-90' # 构建经度线并设置对应经纬度的地理坐标系 lng_lines = gpd.GeoDataFrame({ 'geometry': [LineString([[lng, -90], [lng, -78]]) for lng in np.arange(10, 220, 210 / 38)]}, crs='EPSG:4326') # 构建纬度线并设置为对应经纬度的地理坐标系 lat_lines = gpd.GeoDataFrame({ 'geometry': [LineString([[lng, lat] for lng in range(10, 220)]) for lat in range(-90, -79, 2)]}, crs='EPSG:4326')
构造好数据之后,将经线与纬线对应的GeoDataFrame转换到设置好的「正射投影」crs上,再作为不同图层进行叠加绘制:
按照前面推断出的规则来伪造示例数据,并对伪造过程中的不合理数据进行修正:
def fake_index(value): fake = [] fake.append(value+np.random.uniform(5, 10)) fake.append(value-np.random.uniform(5, 10)) return np.random.choice(fake, size=2, replace=False).tolist() data['购房自由指数'], data['租房自由指数'] = list(zip(*data['居住自由指数'].apply(fake_index))) # 修正伪造数据中大于100和小于0的情况 data.loc[:, '居住自由指数':] = data.loc[:, '居住自由指数':].applymap(lambda v: 100 if v > 100 else v) data.loc[:, '居住自由指数':] = data.loc[:, '居住自由指数':].applymap(lambda v: 0 if v < 0 else v) data.head()
接下来我们就来为每个指标构造线与散点部分的矢量数据,并在统一转换坐标参考系到「正射投影」之后叠加到之前的图像上:
# 为每个城市生成1条经线 lng_lines = gpd.GeoDataFrame({ 'geometry': [LineString([[lng, -90], [lng, -78]]) for lng in np.arange(10, 220, 210 / data.shape[0])]}, crs='EPSG:4326') # 居住自由指数对应的折线 line1 = gpd.GeoDataFrame({ 'geometry': [LineString([(lng, lat) for lng, lat in zip(np.arange(10, 220, 210 / data.shape[0]), data['居住自由指数_映射值'])])]}, crs='EPSG:4326') # 居住自由指数对应的折线上的散点 scatter1 = gpd.GeoDataFrame({ 'geometry': [Point(lng, lat) for lng, lat in zip(np.arange(10, 220, 210 / data.shape[0]), data['居住自由指数_映射值'])]}, crs='EPSG:4326') # 购房自由指数对应的折线 line2 = gpd.GeoDataFrame({ 'geometry': [LineString([(lng, lat) for lng, lat in zip(np.arange(10, 220, 210 / data.shape[0]), data['购房自由指数_映射值'])])]}, crs='EPSG:4326') # 购房自由指数对应的折线上的散点 scatter2 = gpd.GeoDataFrame({ 'geometry': [Point(lng, lat) for lng, lat in zip(np.arange(10, 220, 210 / data.shape[0]), data['购房自由指数_映射值'])]}, crs='EPSG:4326') # 租房自由指数对应的折线 line3 = gpd.GeoDataFrame({ 'geometry': [LineString([(lng, lat) for lng, lat in zip(np.arange(10, 220, 210 / data.shape[0]), data['租房自由指数_映射值'])])]}, crs='EPSG:4326') # 租房自由指数对应的折线上的散点 scatter3 = gpd.GeoDataFrame({ 'geometry': [Point(lng, lat) for lng, lat in zip(np.arange(10, 220, 210 / data.shape[0]), data['租房自由指数_映射值'])]}, crs='EPSG:4326') fig, ax = plt.subplots(figsize=(8, 8)) # 绘制经度线与纬度线 ax = lng_lines.to_crs(crs).plot(ax=ax, linewidth=0.4, edgecolor='lightgrey') ax = lat_lines.to_crs(crs).plot(ax=ax, linewidth=0.75, edgecolor='grey', alpha=0.8) ax = line1.to_crs(crs).plot(ax=ax, color='black', linewidth=1) ax = scatter1.to_crs(crs).plot(ax=ax, color='black', markersize=12) ax = line2.to_crs(crs).plot(ax=ax, color='#00CED1', linewidth=0.6) ax = scatter2.to_crs(crs).plot(ax=ax, color='#00CED1', markersize=4) ax = line3.to_crs(crs).plot(ax=ax, color='lightgrey', linewidth=0.6) ax = scatter3.to_crs(crs).plot(ax=ax, color='lightgrey', markersize=4) ax.axis('off'); # 关闭坐标轴 fig.savefig('图11.png', dpi=500, inches_bbox='tight', inches_pad=0)
那么接下来我们要做的事就so easy了,只需要分别得到两者去除重叠面后,剩余的部分,以对应的填充色彩叠加绘制在图11的图像上就可以啦~,利用geopandas中的difference即可轻松实现:
fig, ax = plt.subplots(figsize=(8, 8)) # 绘制经度线与纬度线 ax = lng_lines.to_crs(crs).plot(ax=ax, linewidth=0.4, edgecolor='lightgrey') ax = lat_lines.to_crs(crs).plot(ax=ax, linewidth=0.75, edgecolor='grey', alpha=0.8) ax = line1.to_crs(crs).plot(ax=ax, color='black', linewidth=1) ax = scatter1.to_crs(crs).plot(ax=ax, color='black', markersize=12) ax = line2.to_crs(crs).plot(ax=ax, color='#00CED1', linewidth=0.6) ax = scatter2.to_crs(crs).plot(ax=ax, color='#00CED1', markersize=4) ax = line3.to_crs(crs).plot(ax=ax, color='lightgrey', linewidth=0.6) ax = scatter3.to_crs(crs).plot(ax=ax, color='lightgrey', markersize=4) ax = polygon1.difference(polygon2).plot(ax=ax, color='#00CED1', alpha=0.2) polygon2.difference(polygon1).plot(ax=ax, color='lightgrey', alpha=0.6) ax.axis('off'); # 关闭坐标轴 fig.savefig('图13.png', dpi=500, inches_bbox='tight', inches_pad=0)
到此,关于“Python怎么实现数据可视化分析38个城市的居住自由指数”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。