热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

r语言和python可视化绘图_用Python来仿制一张R语言的数据可视化图

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。以下文章来源于Python大数据分析,作者费弗里简介开门见山&#x

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

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

简介

开门见山,今天我们要模仿的数据可视化作品来自 「#TidyTuesday」 活动于2020年1月28日发布的「旧金山街道树木数据集」下的众多参赛作品中,由Philippe Massicotte创作的(如图1所示)非常受欢迎的 「Street trees of San Francisco」:

图1

原作者使用的工具是R语言,而今天的文章内容,我就将带大家学习如何在Python中模仿图1的风格进行类似数据信息的可视化展示(其实原作品有一些令人困惑的瑕疵,因此我在下文中在一些地方采用了与原作者不同的分析方式,因此最终的成品与原作品有一些不同之处)。

模仿过程

今天我们要模仿的这张图,咋一看上去似乎略复杂,但如果你曾经阅读过我的「基于geopandas的空间数据分析」系列文章,就一下子可以在脑中将此图构成进行分解:

过程分解

我们仔细观察原作品,可以get到其主要视觉元素是将统计出的数值映射到每个社区面色彩之上,且外围的轮廓描边,很明显是整个地区对应整体的向外缓冲区,再辅以道路网,使得整张图看起来显得很“精密”。

结合我们手头的数据:旧金山社区「面」数据、有登记的街道树木「点」数据,至于道路网「线」数据我们则可以利用第三方库osmnx进行获取(建议利用conda install -c conda-forge osmnx进行安装)。

将过程拆分为下列步骤:

「数据准备」

首先我们需要读入已有的数据并进行相应的矢量化:

而路网数据我们则可以利用osmnx进行在线获取,只需传入我们的旧金山面数据bbox范围,配合

osmnx进行获取即可:

接着我们在上述数据基础上对每个社区面内部的街道树木数量进行统计并对数据进行分箱,配上预设区间的色彩值:

#统计每个社区内部的树木数量

sf_trees =\

(

gpd#空间连接

.sjoin(left_df=sf,

right_df=trees,

op='contains',

how='left')#按照name分组计数(这里未连接到任何数的社区被

#记为1本质上是错误的,但我们绘图分段后这一点不影响)

.groupby('name')

.agg({'name': 'count','geometry': 'first'})

.rename(columns={'name': '数量'})

.reset_index(drop=False)#直接转为GeoDataFrame

.pipe(gpd.GeoDataFrame, crs='EPSG:4326')

)

sf_trees['颜色'] =(

pd

.cut(sf_trees['数量'],

bins=[0, 2500, 5000, 7500, 10000, max(sf_trees['数量'])],

labels=['#e4f1e1', '#c0dfd1', '#67a9a2', '#3b8383', '#145e64'])

)

最后别忘记了我们作为轮廓的缓冲区生成:

#生成轮廓缓冲区

sf_bounds = gpd.GeoSeries([sf.buffer(0.001).unary_union], crs='EPSG:4326')

「主要视觉元素绘制」

做好这些准备后我们直接就可以先将图像的主体元素绘制出来:

importmatplotlib.pyplot as pltfrom matplotlib importfont_manager as fm#设置全局默认字体

plt.rcParams['font.sans-serif'] = ['Times New Roman']

fig, ax= plt.subplots(figsize=(6, 6))#设置背景色

ax.set_facecolor('#333333')

fig.set_facecolor('#333333')#图层1:缓冲区轮廓

ax =(

sf_bounds

.plot(ax=ax, facecolor='none', edgecolor='#cccccc', linewidth=1)

)#图层2:带有树木统计信息的社区面

ax =(

sf_trees

.plot(color=sf_trees['颜色'], edgecolor='#333333',

linewidth=0.5, ax=ax)

)#图层3:osm路网

ax =(

roads

.plot(linewidth=0.05, edgecolor='#3c3d3d',

ax=ax)

)#设置x轴

ax.set_xticks([-122.5, -122.45, -122.4, -122.35])

ax.set_xticklabels(['122.5°W', '122.45°W', '122.4°W', '122.35°W'])#设置y轴

ax.set_yticks([37.72, 37.74, 37.76, 37.78, 37.8, 37.82])

ax.set_yticklabels(['37.72°N', '37.74°N', '37.76°N', '37.78°N', '37.8°N', '37.82°N'])#设置坐标轴样式

ax.tick_params(axis='both', labelcolor='#737373', color='none', labelsize=8)#隐藏周围的spines线条

ax.spines['left'].set_color('none')

ax.spines['right'].set_color('none')

ax.spines['top'].set_color('none')

ax.spines['bottom'].set_color('none')#导出图像

fig.savefig('图4.png', dpi=600, bbox_inches='tight')

「辅助视觉元素的添加」

接下来我们只需要补充上各种点睛之笔的小元素即可,其中值得一提的是下方的图例我们用inset_axes()插入子图的方式灵活实现。

并且外部字体文件的使用也是很添彩的,我们这里就分别在「标题」和「刻度标签」处使用到了两种特殊的字体(你可以在开头的Github仓库找到我用到的所有字体文件):

fig, ax = plt.subplots(figsize=(6, 6))#设置背景色

ax.set_facecolor('#333333')

fig.set_facecolor('#333333')#图层1:缓冲区轮廓

ax =(

sf_bounds

.plot(ax=ax, facecolor='none', edgecolor='#cccccc', linewidth=1)

)#图层2:带有树木统计信息的社区面

ax =(

sf_trees

.plot(color=sf_trees['颜色'], edgecolor='#333333',

linewidth=0.5, ax=ax)

)#图层3:osm路网

ax =(

roads

.plot(linewidth=0.05, edgecolor='#3c3d3d',

ax=ax)

)#设置x轴

ax.set_xticks([-122.5, -122.45, -122.4, -122.35])

ax.set_xticklabels(['122.5°W', '122.45°W', '122.4°W', '122.35°W'])#设置y轴

ax.set_yticks([37.72, 37.74, 37.76, 37.78, 37.8, 37.82])

ax.set_yticklabels(['37.72°N', '37.74°N', '37.76°N', '37.78°N', '37.8°N', '37.82°N'])#设置坐标轴样式

ax.tick_params(axis='both', labelcolor='#737373', color='none', labelsize=8)#隐藏周围的spines线条

ax.spines['left'].set_color('none')

ax.spines['right'].set_color('none')

ax.spines['top'].set_color('none')

ax.spines['bottom'].set_color('none')#以插入子图的方式添加下方图例

ax_bar = ax.inset_axes((0.25, -0.12, 0.5, 0.015))

ax_bar.set_facecolor('#333333')

ax_bar.spines['left'].set_color('none')

ax_bar.spines['right'].set_color('none')

ax_bar.spines['top'].set_color('none')

ax_bar.spines['bottom'].set_color('none')

ax_bar.bar(range(5), [1]*5, width=0.975, color=['#e4f1e1', '#c0dfd1', '#67a9a2', '#3b8383', '#145e64'])

ax_bar.set_yticks([])

ax_bar.set_xticks([i+0.5 for i in range(4)])

ax_bar.set_xticklabels(['2500', '5000', '7500', '10000'],

fontdict={'fontproperties': fm.FontProperties(fname="RobotoCondensed-Regular.ttf")})

ax_bar.tick_params(color='none', labelcolor='#ffffff', labelsize=8, pad=0)

ax.set_title('Street trees of San Francisco',

fontsize=24,

color='#ffffff',

pad=40,

fontproperties=fm.FontProperties(fname="Amaranth-Bold.ttf"))

ax.text(0.5, 1.08, '''There are a total of 192987 trees in San Francisco regrouped into 571 species.

The district with the most number of trees is Mission whereas the one with

the least number of trees is LincoLn Park / Ft. Miley.''', transform=ax.transAxes, ma='center',

ha='center', va='top', color='#ffffff')

ax.text(0.5, -0.22, 'Visualization by CNFeffery', fontsize=8,

color='#737373', ha='center', transform=ax.transAxes)#导出图像

fig.savefig('图5.png', dpi=600, bbox_inches='tight')



推荐阅读
  • 毕业设计:基于机器学习与深度学习的垃圾邮件(短信)分类算法实现
    本文详细介绍了如何使用机器学习和深度学习技术对垃圾邮件和短信进行分类。内容涵盖从数据集介绍、预处理、特征提取到模型训练与评估的完整流程,并提供了具体的代码示例和实验结果。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 基因组浏览器中的Wig格式解析
    本文详细介绍了Wiggle(Wig)格式及其在基因组浏览器中的应用,涵盖variableStep和fixedStep两种主要格式的特点、适用场景及具体使用方法。同时,还提供了关于数据值和自定义参数的补充信息。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 解决Element UI中Select组件创建条目为空时报错的问题
    本文介绍如何在Element UI的Select组件中使用allow-create属性创建新条目,并处理创建条目为空时出现的错误。我们将详细说明filterable属性的必要性,以及default-first-option属性的作用。 ... [详细]
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
author-avatar
hro5028136
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有