专栏名称: 气象学家
【气象学家】公众号平台为您解读最新气象科研进展、分享气象实用编程技巧、追踪气象即时资讯。欢迎加入气象AI和Python交流群以及气象博士群!与5W+的专业人士一起交流互动!
目录
相关文章推荐
廣告狂人  ·  “好炸鸡自有答案”,系列整活简直王炸! ·  13 小时前  
销售与市场  ·  假“饺子”吸粉带货,《哪吒2》被畸形流量围攻了 ·  19 小时前  
廣告狂人  ·  格力改名,市场部天塌了! ·  昨天  
销售与市场  ·  商超“回暖”? ·  昨天  
51好读  ›  专栏  ›  气象学家

地学中顶刊的多条时间序列如何绘图?

气象学家  · 公众号  ·  · 2024-05-04 22:28

正文

第一时间获取气象科研资讯

气象学家 公众号 交流群

加入


在地学中处理多条时间序列

当处理多个时间序列数据时,有效的视觉表现可以极大地影响信息的传达效率和清晰度。在地学研究中,如气候变化、海洋动力学和大气科学等领域,研究者常常需要展示多条时间序列数据,以分析和比较不同模型或变量随时间的变化。然而,多条时间序列的图表如果设计不当,容易造成视觉上的混乱和信息的难以解读。

在数据处理中,我们很容易获取到多条时间序列,将其美观地展示出来不是一件容易的事情,多条折线会让图画变得很凌乱和很复杂。

就像:

一个不好的展示

但有些情况,图也能处理的很好:

下面的b图相较于a图有一定改进
多时间序列的很好展示

在进行数据可视化时,考虑到每条时间序列都可能代表一个独立的变量或模型,有效的区分和表现这些线条变得尤为关键。例如,颜色、线型、线宽、透明度等都是可以用来区分不同序列的视觉工具。此外,图表的布局和尺寸也对阅读效果有重要影响,适当扩展图表的宽度可以帮助减少线条之间的重叠和交错,使得每条线条都能清晰地展示。

这里我们尝试复现一下,如何正确的处理多折线并用python绘图

数据准备

def read_textfile(datadir='/home/mw/project/',
                  filename='Global_Net_Anomaly_Timeseries_12monthMean.txt', skip=1):
    f = open(datadir + filename, "r")
    lines = f.readlines()
    header = lines[skip-1]
    keys = header.split()
    f.close()
    ncols = len(lines[-1].split())  # Get number of columns from the last line..
    nrows = len(lines) - skip  # Get number of data lines in text file
    data = np.zeros([nrows, ncols])  # Convention of rows then columns for Numpy arrays (?)
    for jj in range(nrows):
        for ii in range(ncols):
            data[jj, ii] = float(lines[jj + skip].split()[ii])
    data_dict = dict.fromkeys(keys)
    for kk, key in enumerate(keys):
        data_dict[key] = data[:, kk]
    return data_dict
    
Net_dict = read_textfile()
SW_dict = read_textfile(filename='Global_SW_Anomaly_Timeseries_12monthMean.txt')
LW_dict = read_textfile(filename='Global_LW_Anomaly_Timeseries_12monthMean.txt')

# Include full model names as specified in Loeb et al (2020):
# https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2019GL086705
Net_dict['EC-Earth3-Veg'] = Net_dict['EC-Earth3'
SW_dict['EC-Earth3-Veg'] = SW_dict['EC-Earth3']
LW_dict['EC-Earth3-Veg'] = LW_dict['EC-Earth3']

Net_dict['ECHAM6.3'] = Net_dict['ECHAM'
SW_dict['ECHAM6.3'] = SW_dict['ECHAM']
LW_dict['ECHAM6.3'] = LW_dict['ECHAM']

Net_dict['GFDL-AM4'] = Net_dict['GFDL'
SW_dict['GFDL-AM4'] = SW_dict['GFDL']
LW_dict['GFDL-AM4'] = LW_dict['GFDL']

Net_dict['IPSL-CM6A'] = Net_dict['IPSL'
SW_dict['IPSL-CM6A'] = SW_dict['IPSL']
LW_dict['IPSL-CM6A'] = LW_dict['IPSL']

print(Net_dict.keys())

简单绘图

接下来我们只用Python内置的简单函数来绘制这张图

yr = Net_dict['yr']

for model in ['HadGEM3''ECHAM''EC-Earth3''CESM2''CanESM5','IPSL''GFDL']:
    plt.plot(yr, Net_dict[model], label=model)
plt.plot(yr, Net_dict['CERES'], label='CERES', color='k', linewidth=2.0)
plt.legend(ncol=2)
plt.show()
简单的可视化

简单绘制一张多序列图,效果非常一般,这就需要让我们继续美化:

在上面的例子中,我们尝试使用Python绘图库来制作时间序列图。首先,通过定义一个读取数据的函数,我们从文本文件中提取出所需的时间序列数据。这一步骤是确保数据准确无误地被导入到绘图程序中的关键。然后,通过简单的线图尝试初步绘制,发现结果虽然基本反映了数据趋势,但在视觉表现上还有改进的空间。

深度美化

为了提升图表的可读性和美观性,我们进一步调整绘图参数,例如使用不同颜色来区分观测数据和模型数据,加粗特定的关键数据线,以及调整图例和标题的样式和位置。我们还采用了分面绘图,将不同的物理量(如短波辐射、长波辐射和净辐射)分别在不同的子图中展示,这不仅有助于比较不同模型间的差异,也使得整个图表的结构更为清晰。

c_obs = 'black' # Line color for CERES observations
c_mean = 'darkred' # Line color for multi-model mean
lw_model = 1.0 # Linewidth for individual CMIP models

text1 = """The ensemble mean of available CMIP6 climate models tracks the observed
energy budget changes when forced with observed sea surface temperatures"
""

xmin, xmax = 2000., 2018
ymin, ymax = -1.3, 1.3

plt.figure(1)
f = plt.gcf()
#f.set_size_inches(6.,8.)
matplotlib.rcParams['font.size']=9
matplotlib.rcParams['axes.linewidth']=0.5 # set the value globally

yr = Net_dict['yr']
# In alphabetical order.. 
models = ['CanESM5','CESM2''EC-Earth3-Veg''ECHAM6.3''GFDL-AM4''HadGEM3''IPSL-CM6A']

# Panel A = SW radiation anomaly comparison
ax = plt.subplot(3, 1, 1)
plt.plot([xmin,xmax], [0., 0.], 'grey', linewidth=0.75) # Plot zero line
for model in models:
    color = RGB_dict[model]
    # Adopt Chapter 7 convention of +ve downwards 
    plt.plot(yr, -SW_dict[model], label=None, color=color, linewidth=lw_model)
plt.plot(yr, -SW_dict['multimodel'], label='Model mean', color=c_mean, linewidth=3.0)
plt.plot(yr, -SW_dict['CERES'], label='CERES observations', color=c_obs, linewidth=3.0)
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)
#ax.set_xticklabels('')
ax.yaxis.set_ticks_position('both')
ax.tick_params(width=0.5)
plt.ylabel('W m$^{-2}$')
#plt.title('a) Global mean reflected solar flux anomaly')
plt.title('a) Global mean solar flux anomaly')
plt.legend(loc='upper left', frameon=False, fontsize=8, ncol=4)


# Panel B = LW radiation anomaly comparison
ax = plt.subplot(3, 1, 2)
plt.plot([xmin,xmax], [0., 0.], 'grey', linewidth=0.75) # Plot zero line
for model in models:
    color = RGB_dict[model]
    # Adopt Chapter 7 convention of +ve downwards 
    plt.plot(yr, -LW_dict[model], label=model, color=color, linewidth=lw_model)
plt.plot(yr, -LW_dict['multimodel'], label=None, color=c_mean, linewidth=3.0)
plt.plot(yr, -LW_dict['CERES'], label=None, color=c_obs, linewidth=3.0)
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)
#ax.set_xticklabels('')
ax.yaxis.set_ticks_position('both')
ax.tick_params(width=0.5)
plt.ylabel('W m$^{-2}$')
#plt.title('b) Global mean emitted thermal flux anomaly')
plt.title('b) Global mean thermal flux anomaly')
plt.legend(loc='upper left', frameon=False, fontsize=8, ncol=4)
#plt.legend(loc='lower left', frameon=False, fontsize=8, ncol=4)

# Panel C = Net radiation anomaly comparison
ax = plt.subplot(3, 1, 3)
plt.plot([xmin,xmax], [0., 0.], 'grey', linewidth=0.75) # Plot zero line
for model in models:
    color = RGB_dict[model]
    plt.plot(yr, Net_dict[model], label=None, color=color, linewidth=lw_model)
plt.plot(yr, Net_dict['multimodel'], label=None, color=c_mean, linewidth=3.0)
plt.plot(yr, Net_dict['CERES'], label=None, color=c_obs, linewidth=3.0)
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)
plt.text(2000.5, 1.22, text1, fontsize=8, va='top')
#plt.text(2000.5, 1.1, text2, fontsize=8)
#ax.set_xticklabels('')
ax.yaxis.set_ticks_position('both')
ax.tick_params(width=0.5)
plt.ylabel('W m$^{-2}$')
plt.title('c) Global mean net flux anomaly')
#plt.legend(loc='upper left', frameon=False, fontsize=8, ncol=4)
plt.tight_layout()
深度美化后的结果

最后这张图明显就很好了,我们用到了以下的技巧来美化多条时间序列图。

  • 把图的左右尽可能拉长,长宽比尽量设置为3:1甚至更高。
  • 在多折线中,尽可能淡化非主题因素,一定要突出主体因素,如本图中用了更粗的折线
  • 采用了分面绘图,将不同的物理量(如短波辐射、长波辐射和净辐射)分别在不同的子图中展示






声明: 欢迎转载、转发。气象学家公众号转载信息旨在传播交流,其内容由作者负责,不代表本号观点。文中部分图片来源于网络,如涉及内容、版权和其他问题,请联系小编 (微信:qxxjgzh) 处理。


往期推荐
获取 ERA5/ERA5-Land再分析数据(36TB/32TB)






请到「今天看啥」查看全文