跟着顶级科研报告IPCC学绘图:温度折线/柱图/条带/双y轴

复现IPCC气候变化过程图

引言

升温条带Warming stripes(有时称为气候条带,目前尚无合适且统一的中文释义)是数据可视化图形,使用一系列按时间顺序排列的彩色条纹来视觉化描绘长期温度趋势。

图片

 

在IPCC报告中经常使用这一方案

图片

IPCC是科研报告,同时也是向大众传播信息的媒介,变暖条纹体现了一种“极简主义” ,设想仅使用颜色来避免技术干扰,向非科学家直观地传达全球变暖趋势,非常值得我们学习。

升温条带为何显著?

近年来,极端天气事件越发频繁,而是成为一种常态。2022 年,暴雨季风引发了各地区的洪水事件[1]。另一方面,各个区域经历了几十年来最严重的热浪[2],干旱加剧,影响了中国广大地区的粮食生产、工业和基础设施。在欧洲一些国家,炎热的夏季已经变得越来越多,热浪席卷各处,而十年前情况并非如此。

2020 年,全球气温比工业化前水平高出1.2 °C (IPCC)。到本世纪末(2100 年),气温上升预计将达到约 100%。乐观情景下比工业化前水平高出1.8 ° C,当前政策下比工业化前水平高出2.7 ° C(IPCC)。

科学家们一致认为,到 2100 年,全球气温上升需要限制在比工业化前水平高1.5 °C的范围内,以防止气候系统发生不可逆转的变化(IPCC)。

数据和方法

本文通过 NASA过去 142 年的历史全球温度异常和NOAA的过去几十年二氧化碳全球浓度数据,基于 Python 中的 matplotlib 和 seaborn 包可视化数据。

代码

从 1880 年开始记录以来,全球年平均地表气温变化数据可从 NASA GISS 网站获取:https://data.giss.nasa.gov/gistemp/graphs_v4/

同时文末也提供了本文的数据和代码。

import pandas as pd
df = pd.read_csv('data/graph.csv')
#https://data.giss.nasa.gov/gistemp/graphs_v4/

图片

 

为了可视化的一致性,自定义了 matplotlib 的默认设置。

import matplotlib.pyplot as plt
#figure size and font size
plt.rcParams["figure.figsize"] = (10, 6)
plt.rcParams["font.size"] = 14#grid lines
plt.rcParams["axes.grid"] = True
plt.rcParams["axes.grid.axis"] = "y"#Setting up axes
plt.rcParams['axes.spines.bottom'] = True
plt.rcParams['axes.spines.left'] = False
plt.rcParams['axes.spines.right'] = False
plt.rcParams['axes.spines.top'] = False
plt.rcParams['axes.linewidth'] = 0.5#Ticks
plt.rcParams['ytick.major.width'] = 0
plt.rcParams['ytick.major.size'] = 0

首先进行一个简单的绘制。

import numpy as np
fig, ax = plt.subplots()
df["Annual Mean"].plot(ax = ax, c = "black", marker = "s")
df["Lowess Smoothing"].plot(ax = ax, c = "red")x = df.index.tolist()
y = df["Annual Mean"].tolist()# Define the 95% confidence interval
ci = np.mean(y) + 1.96 * np.std(y) / np.sqrt(len(y))
plt.fill_between(x, y-ci, y+ci,color = "gray",alpha = 0.25,label = "LSAT+SST Uncertainty")ax.axhline(y = 0, linestyle = "--", color = "black")
plt.legend(loc = "upper left")
plt.ylabel("Temperature anomaly w.r.t. 1951-80 mean (°C)")
plt.title("Global surface air temperature change estimates based on land and ocean data")
plt.show()

图片

黑线表示全球年平均地表气温相对于 1951-1980 年平均值的变化。红线是五年最低平滑线。

温度异常数据存在不确定性,这些不确定性源于测量、台站记录和土地覆盖变化导致的系统偏差。灰色阴影区域代表 95% 置信区间

本图也类似于IPCC的一贯表达方式。

本图也类似于IPCC的一贯表达方式。

图片

接下来绘制一个简单的条形图。

df["Annual Mean"].plot(kind = "bar")
years = np.arange(1880, 2022, 20)
plt.xticks(ticks = np.arange(0, 142, 20), labels = years)
plt.title("Global Surface Temperature relative to 1950 to 1980 Mean")
plt.ylabel("Temperature Anomaly (°C)")
plt.show()

图片

现在的条形图很单调,我们想添加温度的映射,首先查看色卡:

my_cmap = plt.get_cmap("coolwarm")
my_cmap

图片

 

映射色卡,这一步功能用seaborn则很方便:(只需要一行代码)

import seaborn as sns
sns.barplot(x = df.index, y = df["Annual Mean"],palette = "coolwarm")
years = np.arange(1880, 2022, 20)
plt.xticks(ticks = np.arange(0, 142, 20), labels = years)
plt.title("Global Surface Temperature relative to 1950 to 1980 Mean")
plt.ylabel("Temperature Anomaly (°C)")
plt.show()

图片

如果使用matplotlib,相对麻烦,思路是用 lambda 匿名函数将温度缩放在 0 1之间。所选颜色图 (coolwarm)my_cmap包含 255 种组合,其中my_cmap([0])指的是蓝色,my_cmap([1])指的是红色。其次,缩放值为每个条纹选择这些颜色y

x = df['Year'].tolist()
y = df["Annual Mean"].values.tolist()
#rescale y between 0 (min) and 1 (max)
rescale = lambda y: (y - np.min(y)) / (np.max(y) - np.min(y))
plt.bar(x, y, color = my_cmap(rescale(y)), width = 0.8)
years = np.arange(1880, 2022, 20)
plt.xticks(ticks = years, labels = years)
plt.title("Global surface temperature relative to 1951-1980 Mean")
plt.ylabel("Temperature Anomaly (°C)"); plt.xlabel("Year")
plt.show()

图片

两张可视化是一致的,接下来想创建升温条带,这里使用PatchCollection功能,这个函数让我们能自定义各种图案。

首先将年平均气温异常读取为 pandas anomaly。然后用PatchCollection为 1880 年至 2021 年间的每一年创建了统一的条纹。数据anomaly相当于 PatchCollection col

from matplotlib.collections import PatchCollection
from matplotlib.patches import Rectangle
#matplotlib.patches.Rectangleanomaly = df["Annual Mean"]fig = plt.figure(figsize = (10, 1.5))
ax = fig.add_axes([0, 0, 1, 1])#turn the x and y-axis off
ax.set_axis_off()#create a collection with a rectangle for each year
col = PatchCollection([Rectangle((y, -1),  #xy1,       #width2        #height) for y in np.arange(1880, 2022)])#use the anomaly data for colormap
col.set_array(anomaly)#apply the colormap colors
cmap = plt.get_cmap("coolwarm")
col.set_cmap(cmap)ax.add_collection(col)#average global temperature lineax.axhline(0, linestyle = "--", color = "white")
df.plot(ax = ax, linestyle = "-", color = "black", legend = False)
#add title and text
ax.set_title("Warming Stripes (1880-2021)", loc = "center", y = 0.75)
ax.text(x = 1880, y = -1, s = "1880")
ax.text(x = 2022, y = -1, s = "2021")ax.set_ylim(-1, 2)
ax.set_xlim(1870, 2030)

图片

全球温度变暖有多方面原因,CO2温室气体是一个主要的原因:截至 2016 年,二氧化碳 (CO2) 占全球温室气体排放量的四分之三,其次是甲烷 (CH₄,17%)、一氧化二氮 (N2O,6%) ,可参考相关报告。

import matplotlib.pyplot as plt
gases = ["CO$_2$", "CH$_4$", "N$_2$O", "F-gases"]
warming_potential = [1, 25, 300, 1000]
text_height = [i*1.2 for i in warming_potential]
text = ["1", "25", "300", "1000+"] 
volume = [74.4, 17.3, 6.2, 2.1]
colors = ["brown", "darkslategray", "darkgray", "purple"]fig, (ax1, ax2) = plt.subplots(1, 2)ax1.bar(gases, warming_potential, color = colors)
for i, height, word in zip(range(4), text_height, text):ax1.text(x = i * 0.9, y = height, s = word)
ax1.set_yscale("log")
ax1.set_title("Global warming potential (GWP)\n by gas over 100-year timescale", y = 1)
ax1.spines.top.set_visible(False)
ax1.spines.right.set_visible(False)autopct = lambda p:f'{p:.1f}%'
ax2.pie(x = volume, radius = 1, startangle = 90, labels = gases,autopct = autopct, pctdistance = 0.8, colors = colors, textprops = {"color":"white"})
ax2.legend(labels = gases, bbox_to_anchor = (0.9, 0.8), ncol = 1)
ax2.set_title("Atmospheric composition of global \nGHG emissions", y = 1.1)plt.tight_layout()
plt.show()

图片

最后将二氧化碳与温度结合在一个图里,创建双y轴图像,来完成本文的收尾~

co2_annual = pd.read_csv('data/co2_annmean_mlo.csv')
# https://gml.noaa.gov/ccgg/trends/global.html#global
rescale = lambda y: (y - np.min(y)) / (np.max(y) - np.min(y))fig, ax1 = plt.subplots()
df_temp = df[df['Year'] >= 1959]
x = df_temp['Year'].tolist()
y = df_temp["mean"].values.tolist()ax1.bar(x, y, color = my_cmap(rescale(y)), width = 0.8)
ax1.set_ylabel("Temperature anomaly \n relative to 1951-80 mean (°C)", color = "red")
ax1.tick_params(axis='y', color='red', labelcolor='red')
ax1.grid(False)#Add twin axes
ax2 = ax1.twinx()
ax2.plot(x, co2_annual['mean'], color = "black", marker = "o", markersize = 4)
ax2.set_ylabel("CO$_2$ (ppm)")
ax2.grid(False)ax2.tick_params(axis='y')for pos in ["top"]:ax1.spines[pos].set_visible(False)ax2.spines[pos].set_visible(False)plt.grid()
plt.title("Global temperature anomaly and atmospheric CO$_2$ emissions concentration\n (1959-2021)",pad = 20)plt.show()

图片

reference

  1. https://www.nytimes.com/2022/09/14/world/asia/pakistan-floods.html

  2. https://multimedia.scmp.com/infographics/news/china/article/3190803/china-drought/index.html

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

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

相关文章

认识柔性数组

在C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员 限制条件是: 结构体中最后一个成员未知大小的数组 1.柔性数组的形式 那么我们怎样写一个柔性数组呢 typedef struct st_type {int i;int a[0];//柔性数组成员 }ty…

SpringBoot 可以同时处理多少请求

一、前言 首先,在Spring Boot应用中,我们可以使用 Tomcat、Jetty、Undertow 等嵌入式 Web 服务器作为应用程序的运行容器。这些服务器都支持并发请求处理的能力。另外,Spring Boot 还提供了一些配置参数,可以对 Web 服务器进行调…

互联网Java工程师面试题·MyBatis 篇·第二弹

目录 16、Xml 映射文件中,除了常见的 select|insert|updae|delete标签之外,还有哪些标签? 17、Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复? 18、为什么说 Mybatis 是半自动 ORM 映射…

Vue项目搭建图文详解教程

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 预备工作 请在本地创建文件夹用于存放Vue项目,例如:创建HelloWorld文件夹存放即将创建的Vue新项目。 创建Vue项目 首先,请在DOS中将目录…

踩坑 | vue动态绑定img标签src属性的一系列报错

文章目录 踩坑 | vue项目运行后使用require()图片也不显示问题描述vue中动态设置img的src不生效问题的原因require is not defined 解决办法1:src属性直接传入地址解决办法2 踩坑 | vue项目运行后使用require()图片也不显示 问题描述 在网上查阅之后,发…

深度学习笔记之线性代数

深度学习笔记之线性代数 一、向量 在数学表示法中,向量通常记为粗体小写的符号(例如,x,y,z)当向量表示数据集中的样本时,它们的值具有一定的现实意义。例如研究医院患者可能面临的心脏病发作风…

<C++> STL_bitset使用和模拟实现

bitset的介绍 位图的引入 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中? 要判断一个数是否在某一堆数中,我们可能会想到如下方法: 将这一堆数进行排序&#xff0…

Linux-正则三剑客

目录 一、正则简介 1.正则表达式分两类: 2.正则表达式的意义 二、Linux三剑客简介 1.文本处理工具,均支持正则表达式引擎 2.正则表达式分类 3.基本正则表达式BRE集合 4.扩展正则表达式ere集合 三、grep 1.简介 2.实践 3.贪婪匹配 四、sed …

STM32Cubemx新建F429基础工程

配置STM32CubeMX 配置KEY 配置USART1 配置RCC Project Manager Toolchain 选择 MDK-ARM Code Generator 配置如下 GENERATE CODE 即可 配置Keil5 魔术棒配置 – Target – 勾选 Use MicroLIB – Debug – Flash Download – 勾选Reset and Run 基础代码 /* Private incl…

GD32F103x IIC通信

1. IIC通信 1.IIC的介绍 IIC总线有两条串行线,其一是时钟线SCK(同步),其二是数据线SDA。只有一条数据线属于半双工。应用中,单片机常常作为主机,外围器件可以挂载多个。(当然主机也可以有多个。…

AJAX--Express速成

一、基本概念 1、AJAX(Asynchronous JavaScript And XML),即为异步的JavaScript 和 XML。 2、异步的JavaScript 它可以异步地向服务器发送请求,在等待响应的过程中,不会阻塞当前页面。浏览器可以做自己的事情。直到成功获取响应后&#xf…

【Spring MVC】MVC如何浏览器请求(service方法)

文章目录 1. DispatcherServlet 的 service 方法1.1. processRequest 方法1.2. doService 方法 背景:平时我们学习 MVC 重点关注的时DispatcherServlet 的 doDispatcher 方法,但是在 doDispatcher 方法之前 还有请求处理的前置过程,这个过程…

vue 使用 创建二维数组响应数据 渲染 echarts图标

目前我遇到的情况就是用动态的二维数组数据渲染echarts图标,我们从后端收到的接口一般是个一维数组,需要手动构建并且保证响应式。接下来我做了个案例 一、案例总逻辑 1. 先创建一个vue项目 2. 添加 echarts依赖 3. 模拟数据请求,构建二维数组…

Axios post请求出现500错误

笔者在编写前端form表单传后端数据的时候,出现了以下问题 一、问题场景 当我用axios发送post请求的时候,出现了500错误 笔者找了很长时间错误,代码没问题,后端接口也没问题,后来发现问题出在实体类上了 当前端post请…

数据结构: 数组与链表

目录 1 数组 1.1 数组常用操作 1. 初始化数组 2. 访问元素 3. 插入元素 4. 删除元素 5. 遍历数组 6. 查找元素 7. 扩容数组 1.2 数组优点与局限性 1.3 数组典型应用 2 链表 2.1 链表常用操作 1. 初始化链表 2. 插入节点 3. 删除…

10.03

代码 #include <iostream>using namespace std; class cz { private:int num1; //实部int num2; //虚部 public:cz(){}cz(int a,int b):num1(a),num2(b){}cz(const cz &other):num1(other.num1),num2(other.num2){}~cz(){}const cz operator(const cz &othe…

websocket逆向【python实现http/https拦截】

python实现http拦截 前言:为什么要使用http拦截一、技术调研二、技术选择三、使用方法前言:为什么要使用http拦截 大多数爬虫玩家会直接选择API请求数据,但是有的网站需要解决扫码登录、Cookie校验、数字签名等,这种方法实现时间长,难度高。需求里面不需要高并发,有没有…

5月22日比特币披萨日,今天你吃披萨了吗?

比特币披萨日 1. Laszlo Hanyecz2. 最贵披萨诞生记3. 梭哈买披萨4. 未完待续 2010年5月22日&#xff0c;美国佛罗里达州的程序员Laszlo Hanyecz&#xff08;拉兹洛哈涅克斯&#xff09;用10000个比特币购买了棒约翰&#xff08;Papa Johns&#xff09;比萨店一个价值25美元的奶…

C语言:选择+编程(每日一练Day9)

目录 选择题&#xff1a; 题一&#xff1a; 题二&#xff1a; 题三&#xff1a; 题四&#xff1a; 题五&#xff1a; 编程题&#xff1a; 题一&#xff1a;自除数 思路一&#xff1a; 题二&#xff1a;除自身以外数组的乘积 思路二&#xff1a; 本人实力有限可能对…

C++核心编程--继承篇

4.6、继承 继承是面向对象三大特征之一 有些类与类之间存在特殊的关系&#xff0c;例如下图中&#xff1a; ​ 我们发现&#xff0c;定义这些类的定义时&#xff0c;都拥有上一级的一些共性&#xff0c;还有一些自己的特性。那么我们遇到重复的东西时&#xff0c;就可以考虑使…