Python数据可视化:分析38个城市的居住自由指数

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。

以下文章来源于Python大数据分析 ,作者费弗里

1 简介

前不久「贝壳研究院」基于其丰富的房地产相关数据资源,发布了「2020 新一线城市居住报告」

 

而在这个报告中有几张数据可视化作品还是比较可圈可点的,作为(在模仿中精进数据可视化)系列文章的开篇之作,我将基于我观察原始数据可视化作品进而构思出的方式,以纯Python的方式模仿复刻图2所示作品:

 

 

2 复刻过程

2.1 观察原作品

其实原作品咋一看上去有点复杂,但经过观察,将原始图片主要元素拆分成几个部分来构思复现方式,还是不算复杂的,我总结为以下几部分:

  • 「1 坐标系部分」

稍微懂点数据可视化的人应该都可以看出原作品的坐标不是常规的笛卡尔坐标系,而是极坐标系,这里复现原作品极坐标系的难点在于,其并不是完整的极坐标系,即左边略小于半圆的区域是隐藏了参考线的。

因此与其在matplotlib中极坐标系的基础上想方法隐藏部分参考线,不如逆向思维,从构造参考线的角度出发,自己组织构造参考线,会更加的自由和灵活。

  • 「2 颜色填充」

这里的「颜色填充」指的是以居住自由指数折线为中线,在购房自由指数折线与租房自由指数折线之间的颜色填充区域,但困难的是这里当购房自由指数高于租房自由指数时对应的颜色为浅蓝绿色,而反过来则变为灰色,与购房自由指数、租房自由指数的颜色相呼应。

 

2.2 开始动手!

综合考虑前面这些难点,我决定借助matplotlib+geopandas+shapely操纵几何对象和绘制调整图像的方便快捷性,来完成这次的挑战。

2.2.1 构建坐标系统

因为极坐标系中的参考线非常类似俯视南北极点所看到的经纬线,因此我们可以利用地图学中坐标参考系里的「正射投影」(Orthographic),可以理解为纯粹的半球:

 

我们只需要设定中心点参数在南极点或北极点,再配合简单的经纬度相关知识就可以伪造出任意的经纬线,再利用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 warningsplt.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上,再作为不同图层进行叠加绘制:

 

嘿嘿,是不是底层的参考线已经有内味了~

2.2.2 绘制指标折线

坐标系以及参考线的逻辑定了下来之后,接下来我们需要将原作品中所展现的3种指标数据转换为3条样式不同的折线。

首先我们来准备数据,因为原报告中只能找到居住自由指数的具体数值,其他两个指标未提供,因此我们可以结合这3个数值的相互关系,推断出每个城市的购房自由指数与租房自由指数1个比自身的居住自由指数高,1个比居住自由指数低的规律来「伪造」数据:

 

按照前面推断出的规则来伪造示例数据,并对伪造过程中的不合理数据进行修正:

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()

 

至此我们的数据已经伪造完成,接下来我们需要做的事情是对我们的指标值进行变换,使其能够适应前面所确立的坐标系统。

虽然严格意义上说俯视南极点所看到的每一段等间距的纬度带随着其越发靠近赤道,在平面上会看起来越来越窄,但因为我们选取的是南纬-90度到南纬-80度之间的区域,非常靠近极点,因此可以近似视为每变化相同纬度宽度是相等的。

利用下面的函数实现0-100向-90到-80的线性映射:

 

接下来我们就来为每个指标构造线与散点部分的矢量数据,并在统一转换坐标参考系到「正射投影」之后叠加到之前的图像上:

# 为每个城市生成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)

 

哈哈,是不是更加有内味了~,至此,我们的绘制指标折线部分已完成。

2.2.3 绘制填充区域

在相继解决完「坐标系统」「指标折线绘制」之后,就到了最好玩的部分了,接下来我们来绘制图中购房自由指数与租房自由指数之间的折线,并且要按照「填充较大值对应色彩」的原则来处理,接下来我们需要用到一点简单的拓扑学知识,首先我们分别构造购房自由指数_映射值和租房自由指数_映射值引入南极点后所围成的多边形:

 

 

接下来我们先暂停下来思考思考,购房自由指数_映射值与租房自由指数_映射值之间彼此高低起伏交错而形成的填充区域对应着上面两个多边形之间的什么关系?没错!就是就是两者去除掉彼此重叠区域后各自剩余的部分!

 

那么接下来我们要做的事就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)

 

2.2.4 补充文字、标注等元素

其实到这里,我们就已经完成了对原作品复刻的精髓部分了,剩下的无非是添加些文字、刻度之类的,其实这部分很多都可以在出图之后利用其他软件PS完成,比写代码轻松,所以这部分只对添加「城市+指标」的文字标签以及刻度值进行补充:

 

再模仿原作品裁切一下图片,主要元素是不是非常一致了~,大家也可以根据自己的喜好来修改不同的颜色:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/71374.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国内最适合年轻人旅游的地方

NO.1 丽江古城&#xff08;云南省丽江市&#xff09; 上榜理由&#xff1a;从 人们发现丽江开始&#xff0c;就为这里赋予了种种与爱情有关的定义。这里是爱情的天堂&#xff0c;空气里都微微散发着香甜的暧昧气。在小旅馆的露台上相拥着看雪山环抱&#xff1b;牵手漫 步四方街…

如何选择最适合自己的地图软件

在我们的日常生活中&#xff0c;无论是查找地址&#xff0c;亦或是订餐后跟踪送餐的情况&#xff0c;都需要使用地图软件。地图软件对日常生活的影响是不可否认的。然而要找到合适的软件&#xff0c;了解个人的需求至关重要。 也许您想创建一张信息图&#xff0c;一张学校项目的…

全球国家、省/州、城市的数据库(中,英版)

感谢腾讯提供的技术支持! 英文版本:安装QQ国际版,找到对应文件(如下图) 中文版本:安装QQ最新版,找到对应文件(如下图)

Agoda研究显示:上海是中国游客春节最受欢迎的城市之一

农历新年历来是亚太地区游客重要的年度旅行时段&#xff0c;今年Agoda发布的研究显示&#xff0c;新冠疫情后旅游模式日新月异。今年&#xff0c;游客们在重温传统旅游胜地的同时&#xff0c;也发现了一些小众的旅游目的地。家庭或团体游是受欢迎的旅行类型&#xff0c;一些游客…

想分析最热门城市?这个人口热力图你一定要学会制作

​相信大家都见过热力图&#xff0c;特别是分析人口密集程度的时候。 现在数据可视化非常普遍&#xff0c;为了给予大众更加直观的感受&#xff0c;我们不再局限于传统的数据表格&#xff0c;而是采用多样性的可视化的方式&#xff0c;简单明了又便于大众的接受。因此&#xf…

你最想去的城市有哪些?有哪些好的旅游城市?

1.西安 西安是中国最佳旅游目的地、中国国际形象最佳城市之一 &#xff0c;有两项六处遗产被列入《世界遗产名录》&#xff0c;分别是&#xff1a;秦始皇陵及兵马俑、大雁塔、小雁塔、唐长安城大明宫遗址、汉长安城未央宫遗址、兴教寺塔 。另有西安城墙、钟鼓楼、华清池、终南山…

图话第一代女性开发者

写在前面的话 想问大家一个有趣的问题&#xff0c;大家知道我们程序员圈的第一位女性开发者是谁吗&#xff1f;作为开发者&#xff0c;以前并没有认真去想过这个问题&#xff0c;这两天认真的看了一下百度百科查找了一下相关的专业知识。才知道历史上第一位女性程序员是&#x…

GPT-2:OpenAI的NLP商业化野望

文章回顾了近几年NLP的升级历程&#xff0c;从三个阶段的发展带我们梳理了NLP演进的脉络。 自然语言处理&#xff08;NLP&#xff09;技术正在生活的方方面面改变着我们的生活。客厅的智能音箱在跟你每天的对话中飞速进步&#xff0c;甚至开始跟你“插科打诨”来适应你的爱好习…

Java 反射最终篇 - Mock 对象和桩

Mock 对象和 **桩&#xff08;Stub&#xff09;**在逻辑上都是 Optional 的变体。他们都是最终程序中所使用的“实际”对象的代理。 不过&#xff0c;Mock 对象和桩都是假扮成那些可以传递实际信息的实际对象&#xff0c;而不是像 Optional 那样把包含潜在 null 值的对象隐藏。…

用聊天机器人假扮人类

日前看到新闻&#xff0c;某企业用聊天机器人假扮人类&#xff0c;蒙骗消费者。使用聊天机器人服务消费者没有错&#xff0c;但是现在这样用&#xff0c;技术明显是跑在法律前面了&#xff0c;至少在中国还没有立法&#xff0c;禁止机器人假扮人类。 2019年&#xff0c;美国加…

chatgpt赋能python:如何用Python赚取合法收入

如何用Python赚取合法收入 随着技术的飞速发展&#xff0c;Python作为一种简洁易读的高级编程语言&#xff0c;一直以来受到了广大工程师、开发人员和数据科学家的青睐。应用广泛&#xff0c;从网站开发到机器学习&#xff0c;从自然语言处理到大数据分析&#xff0c;Python都…

你需要了解的 50 个 ChatGPT 统计数据和事实

Rest assured that with the ChatGPT statistics you’re about to read, you’ll confirm that the popular chatbot from OpenAI is just the beginning of something bigger. Since its launch in November 2022, ChatGPT has broken unexpected records. For example, it r…

做设计师要用到的工具软件

1.图形处理工具 这就是 UI 设计师的核心了&#xff0c;PS 是使用最广泛的&#xff0c;用 Sketch&#xff08;Mac&#xff09;和 XD&#xff08;Windows&#xff09;的也很多&#xff0c;Sketch/XD 比较轻量级&#xff0c;基本能满足 UI 设计师的日常工作需要。 2.信息架构工具…

解决论文查重时参考文献被标红的方法

1. 有明显的“参考文献”标记&#xff0c;参考文献4个字独占一行&#xff0c;不要有其他任何字符 2. 尽量不要用谷歌学术、NoteExpress、EndNote等工具来生成参考文献&#xff0c;很容易在查重时被标红 2.1 如果用NoteExpress插入参考文献时&#xff0c;最好清除域代码&#…

借助ChatGPT的「代码解释器」,菜鸟玩下数据分析

大家好&#xff0c;我是Yuan&#xff0c;这篇文章主要是介绍&#xff0c;借助ChatGPT的「代码解释器」&#xff0c;如何进行数据分析。 概述 代码解释器对于经常使用代码和数据的专业人士和爱好者都非常有用&#xff0c;这是一个多功能的工具&#xff0c;可以用于分析数据、创…

微信小程序云开发———云数据库

1.微信小程序注册 官方注册文档:[https://developers.weixin.qq.com/miniprogram/introduction/] 微信小程序注册地址&#xff1a;[https://mp.weixin.qq.com/] 进去以后点击立即注册 ​​​​​​​ 点击立即注册后会转跳到选择注册的帐号类型 &#xff0c;在这个页面…

小程序(四):微信登录功能的实现+云开发数据库

目录 好文推荐: 完整代码gitee仓库查看:https://gitee.com/CMD-UROOT/xzyy.git 一、微信登录 1.点击按钮&#xff08;或其他&#xff09;&#xff0c;获取用户信息&#xff08;昵称、头像等&#xff09;。 2.通过微信官方文档搜getUserProfile 3.给点击登录绑定事件 点击登…

微信小程序云开发之云函数的大坑

不知道大家在弄使用云函数的时候有没有看日志的习惯&#xff0c;看这个日志是要钱的&#xff0c;真是无语了&#xff0c;微信开发者工具上面没有任何的提示&#xff0c;我是今天敲代码的时候突然那发现云函数查不出数据了&#xff0c;打开控制台发现说我欠费了&#xff0c;但是…

网页中文翻译成英文简单方法

利用谷歌浏览器的翻译功能可以比较快键的把网页翻译成其他语言。 首先&#xff0c;打开需要翻译的网页。右键一键翻译。 会出现这个选择框&#xff0c;选择选项 改成需要的语言&#xff0c;再按f12。 选择copy 整个html元素&#xff0c;建立一个记事本&#xff0c;复制粘贴。放…

利用python批量将excel中文翻译成英文

目录 操作过程中不断遇到新的问题,思路的转换过程背景第一天 操作过程第二天正则表达式是个好东西第三天第四天第五天遇到的小问题操作过程中不断遇到新的问题,思路的转换过程 背景 今天接到一个任务,需要将EXCEL文件中的中文翻译成英文,由于表格内容非常大,我想着 这要…