当前位置:   article > 正文

python - 科研文献作图复现1_文献复现

文献复现

记录阅读文献过程中,通过python复现原文的一些脚本

  • 想要复现的文章原图如下所示

在这里插入图片描述
原文链接:

  • https://file.scirp.org/Html/4-2430166_82999.htm

首先,对于原图进行简要观察。

  • 这是一张折线图,绘制了6条不同颜色的折线来表示不同变量,横轴的单位统一为时间:月份的英文首字母缩写。比较有意思的是,每个y轴的上限都是不同的,每条曲线对应的标签也是不同的,y轴对应的标签也不同的。同时,每条曲线的y轴将小的间隔也显示出来了。
  • 这里简要分析得到:原文作者可能是将6个子图拼接起来,对于各个子图的边框进行一些调整,使得让人感觉是绘制在一张图上。所以,主要解决6个子图无缝连接的问题就可以还原原图了。
  • 以下是主要复现的point:
    • 多子图上下边界凭借
    • 子图y轴显示为不同位置,原本默认在左侧,需要调制至右侧
    • 子图y轴标签的颜色

这里主要用到两个库: matplotlib(绘图)、numpy(数据),为了减少代码量,这里仅以3个子图举例。

多子图的拼接

import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0, 12, 1) # 横坐标数据为从0到10之间,步长为0.1的等差数组
y = np.sin(x) # 纵坐标数据为 x 对应的 sin(x) 值
plt.rcParams['font.family'] = 'Times New Roman'
fig, axs = plt.subplots(3, 1, sharex=True,dpi=200)
# Remove horizontal space between axes
fig.subplots_adjust(hspace=0.0)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里,通过调整hspace这个参数就可以实现多子图之间的距离:
hspace=0.0在这里插入图片描述
hspace=0.5
在这里插入图片描述
hspace=-0.5
在这里插入图片描述

调整子图的边框

这里需要将第一个子图的下边框、第二个子图的上下边框、以及第三个子图的上边框设置为不可见:

axs[0].spines['bottom'].set_color('none')
axs[1].spines['bottom'].set_color('none')
axs[1].spines['top'].set_color('none')
axs[2].spines['top'].set_color('none')
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
这里加了一点额外的内容,将不同子图y轴以及y轴每个单位对应标签的颜色分别设置为红色、蓝色和黑色:

axs[0].spines.left.set_color('r')
axs[0].spines.right.set_color('r')
axs[1].spines.right.set_color('b')
axs[1].spines.left.set_color('b')

axs[0].tick_params(axis='y',colors='r')
axs[1].tick_params(axis='y',colors='b')
axs[2].tick_params(axis='y',colors='k')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述
这里随便绘制三条曲线:

x = np.arange(0, 12, 1) # 横坐标数据为从0到10之间,步长为0.1的等差数组
y = np.sin(x) # 纵坐标数据为 x 对应的 sin(x) 值
axs[0].plot( x,y,'r',label='red')
axs[1].plot(x,-y,'b',label='blue')
axs[2].plot(x,y*y,'k',label='black')
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

设置y轴单位的位置为右侧,并设置x轴的单位为月份

这里自定义设置x轴的单位,需要注意一个问题,你x轴的array有12个,你对应的xlabels就得是12个,数量要对的上,不然会报错。(可以用空的' '

axs[1].yaxis.set_ticks_position('right')  # axs[0].yaxis.tick_right()
axs[0].set_xticks(x)
axs[0].set_xticklabels(['J','F','M','A','M','J','J','A','S','O','N','D'],rotation=45)
  • 1
  • 2
  • 3

在这里插入图片描述

添加y轴的label,并设置y轴的label在子图的右侧

axs[0].set_ylabel('fig1_ylabel',c='r')
axs[1].set_ylabel('fig2_ylabel',labelpad=-370,c='b')
axs[2].set_ylabel('fig3_ylabel')
  • 1
  • 2
  • 3

在这里插入图片描述

使各个子图的左右上下的边框的tick对称:

axs[0].tick_params(which='major', 
                    direction='out', 
                    bottom=False, left=True, right=True, top=True)
axs[1].tick_params(which='major', 
                    direction='out', 
                    bottom=False, left=True, right=True, top=False)
axs[2].tick_params(which='major', 
                    direction='out', 
                    bottom=True, left=True, right=True, top=False)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里插入图片描述

设置y轴tick的单位间隔,显示最小的单位间隔

from matplotlib.ticker import AutoMinorLocator, MultipleLocator
axs[0].tick_params(which='minor', 
                    direction='out', 
                    colors='r')
for i ,ax in enumerate(axs):
    print(i)
    ax.tick_params(which='both', 
                        direction='out', 
                        left=True, right=True,
                        width=2,
                        )
    ax.yaxis.set_minor_locator(AutoMinorLocator(5))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述
最后,将代码封装一下,再加一点其他的:

import matplotlib.pyplot as plt
import numpy as np


def plot_line():
    
    plt.rcParams['font.family'] = 'Times New Roman'
    fig, axs = plt.subplots(3, 1, sharex=True,dpi=200)
    # Remove horizontal space between axes
    fig.subplots_adjust(hspace=0)
    #################################################################################
    ####                            set  spines color
    #################################################################################
    axs[0].spines['bottom'].set_color('none')
    axs[1].spines['bottom'].set_color('none')
    
    axs[1].spines['top'].set_color('none')
    axs[2].spines['top'].set_color('none')
    axs[0].spines.left.set_color('r')
    axs[0].spines.right.set_color('r')
    axs[1].spines.right.set_color('b')
    axs[1].spines.left.set_color('b')
    
    axs[0].tick_params(axis='y',colors='r')
    axs[1].tick_params(axis='y',colors='b')
    axs[2].tick_params(axis='y',colors='k')
    #################################################################################
    ####                             plot line
    #################################################################################
    
    x = np.arange(0, 12, 1) # 横坐标数据为从0到10之间,步长为0.1的等差数组
    y = np.sin(x) # 纵坐标数据为 x 对应的 sin(x) 值
    axs[0].plot( x,y,'r',label='red')
    axs[1].plot(x,-y,'b',label='blue')
    axs[2].plot(x,y*y,'k',label='black')
    #################################################################################
    ####                             set yticks position
    #################################################################################
    axs[1].yaxis.set_ticks_position('right')  # axs[0].yaxis.tick_right()
    axs[0].set_xticks(x)
    axs[0].set_xticklabels(['J','F','M','A','M','J','J','A','S','O','N','D'],rotation=45)
    
    axs[0].set_ylabel('fig1_ylabel',c='r')
    axs[1].set_ylabel('fig2_ylabel',labelpad=-370,c='b')
    axs[2].set_ylabel('fig3_ylabel')
    axs[2].set_xlabel('Time : month')
    
    
    
    axs[0].tick_params(which='major', 
                        direction='out', 
                        bottom=False, left=True, right=True, top=True)
    axs[1].tick_params(which='major', 
                        direction='out', 
                        bottom=False, left=True, right=True, top=False)
    axs[2].tick_params(which='major', 
                        direction='out', 
                        bottom=True, left=True, right=True, top=False)
    
    from matplotlib.ticker import AutoMinorLocator, MultipleLocator
    axs[0].tick_params(which='minor', 
                        direction='out', 
                        colors='r')
    for i ,ax in enumerate(axs):
        print(i)
        ax.tick_params(which='both', 
                            direction='out', 
                            left=True, right=True,
                            width=2,
                            )
        ax.yaxis.set_minor_locator(AutoMinorLocator(5))
        
    fig.legend(['red','blue','black'],ncol=3,
               bbox_to_anchor=(0.56,1),frameon=False)    
    plt.show()
if __name__=='__main__':

    print('drawing ')
    plot_line()
    # if i<2:
        # ax.spines['bottom'].set_color('none')
        # ax.tick_params(which='major',bottom=False)
        # ax.tick_params(axis='y',direction='out',length=4,)
# x = np.random.random(15)
# y = x

# axs[1].axis["right2"] = ax.new_fixed_axis(loc="right", offset=(20, 0))
# axs[1].axis["right2"].label.set_text("Label Y2")

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

在这里插入图片描述
除了数据的部分,其他都可以通过参数自由调整,总体来说还是

此外,使用 fig.add_axes([])可以更灵活的设置子图的位置,这里就不展示了。代码中许多地方可以更简洁,使用循环或者封装的使得代码更简便,这里仅仅展示最基本的还原过程,欢迎大家分享更好更简单快捷的方法。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/781869
推荐阅读
相关标签
  

闽ICP备14008679号