• 【Matplotlib】学术论文黑白柱状图绘制


    一. 前言

    在学术论文中,当涉及黑白打印时 ,彩色的柱状图往往很难有效地区分,因此我们需要绘制黑白柱状图,并通过添加不同的条纹来实现柱状图的区分。

    接下来我将以下面这组数据为例,绘制几款比较常见的柱状图。

    # 数据代表一年12个月小明和小刚的智商(纯属捏造)
    x = [for i in range(1,13)]
    xiaoming = [111,124,101,132,127,114,140,135,104,120,101,118]
    xiaogang = [132,142,121,101,114,135,126,116,105,131,97,102]
    
    • 1
    • 2
    • 3
    • 4

    二. 柱形图绘制

    2.1 基础绘制

    import numpy as np
    import matplotlib.pyplot as plt
    
    # 数据代表一年12个月小明和小刚的智商(纯属捏造)
    x = [i for i in range(1,13)]
    xiaoming = [111,124,101,132,127,114,140,135,104,120,101,118]
    xiaogang = [132,142,121,101,114,135,126,116,105,131,97,102]
    
    plt.rcParams['font.family'] = ['Times New Roman']
    fig,ax = plt.subplots(1,1,figsize=(7,4.5),dpi=200)
    width = 0.35  # 柱子宽度
    
    #字体设置
    label_font = {
        'weight':'bold',
        'size':14,
        'family':'SimHei'
    }
    
    rects = ax.bar(x, xiaoming, width ,ec='k',color='white',  #x代表刻度值范围
                    lw=.8,hatch='//')
    
    ax.tick_params(axis='x',direction='out',length=5,width=1.5,labelsize=11,bottom=True)#x轴刻度设置
    ax.set_xlabel('月份',fontdict=label_font) #x轴名称
    #set_xticks(x)和set_xticklabels(x)一般一起使用
    ax.set_xticks(x) #设置显示刻度标签的位置,最好与ax.bar的第一个参数一致
    ax.set_xticklabels(x)#设置刻度值对应的标签,可以是字符串型
    
    ax.tick_params(axis='y',direction='out',length=5,width=1.5,labelsize=11,bottom=False) #y轴刻度设置
    ax.set_ylabel('智商',fontdict=label_font) #y轴名称
    ax.set_ylim(ymin = 90,ymax = 150) #y轴刻度范围
    ax.set_yticks(np.arange(90,151,10)) #设置显示刻度标签的位置
    ax.set_yticklabels(np.arange(90,151,10))#设置刻度值对应的标签,可以是字符串型
    
    ax.axhline(0, color='black',alpha=0.5) #绘制y=0的线
    ax.legend(loc='best',markerscale=10,fontsize=12) #设置图例
    
    # 添加数据标签
    def autolabel(rects):
        for rect in rects:
            height = rect.get_height()
            if height>0:
                ax.annotate('{}'.format(height),
                        xy=(rect.get_x() + rect.get_width() / 2, height),
                        xytext=(0, 3),  # 3 points vertical offset
                        textcoords="offset points",
                        ha='center', va='bottom')
            else:
                ax.annotate('{}'.format(height),
                        xy=(rect.get_x() + rect.get_width() / 2, height),
                        xytext=(0, -13),  # 3 points vertical offset
                        textcoords="offset points",
                        ha='center', va='bottom')
    autolabel(rects)
    fig.tight_layout()
    #保存图片  
    #plt.savefig(r'E:\Data_resourses\DataCharm 公众号\Python\学术图表绘制\barplot05.png',dpi=600,bbox_inches = 'tight')
    
    • 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

    在这里插入图片描述
    ax.bar函数中的hatch=参数即可设置柱形图的条纹,包括\,|,/,.,o,+,-,x等。

    2.2 两组数据并列绘制

    import numpy as np
    import matplotlib.pyplot as plt
    
    
    # 数据代表一年12个月小明和小刚的智商(纯属捏造)
    x = [i for i in range(1,13)]
    xiaoming = [111,124,101,132,127,114,140,135,104,120,101,118]
    xiaogang = [132,142,121,101,114,135,126,116,105,131,97,102]
    
    #plt.rcParams['font.sans-serif'] = ['SimHei']
    
    plt.rcParams['font.family'] = ['Times New Roman']
    fig,ax = plt.subplots(1,1,figsize=(7,4.5),dpi=200)
    width = 0.35  # 柱子宽度
    
    #字体设置
    label_font = {
        'weight':'bold',
        'size':14,
        'family':'SimHei'
    }
    legend_font = {
        'weight':'bold',
        'size':10,
        'family':'SimHei'
    }
    
    rects1 = ax.bar(x = [i - 0.2 for i in x], height = xiaoming, width = width ,ec='k',color='white',  
                    lw=.8, label = "小明", hatch='//')
    rects2 = ax.bar(x = [i + 0.2 for i in x], height = xiaogang, width = width ,ec='k',color='white',  
                    lw=.8, label = "小刚", hatch='xxxxxx')
    
    ax.tick_params(axis='x',direction='out',length=5,width=1.5,labelsize=11,bottom=True)#x轴刻度设置
    ax.set_xlabel('月份',fontdict=label_font) #x轴名称
    #set_xticks(x)和set_xticklabels(x)一般一起使用
    ax.set_xticks(x) #设置显示刻度标签的位置,最好与ax.bar的第一个参数一致
    ax.set_xticklabels(x)#设置刻度值对应的标签,可以是字符串型
    
    ax.tick_params(axis='y',direction='out',length=5,width=1.5,labelsize=11,bottom=False) #y轴刻度设置
    ax.set_ylabel('智商',fontdict=label_font) #y轴名称
    ax.set_ylim(ymin = 90,ymax = 150) #y轴刻度范围
    ax.set_yticks(np.arange(90,151,10)) #设置显示刻度标签的位置
    ax.set_yticklabels(np.arange(90,151,10))#设置刻度值对应的标签,可以是字符串型
    
    ax.axhline(0, color='black',alpha=0.5) #绘制y=0的线
    ax.legend(loc='best',markerscale=8,fontsize=10,prop=legend_font) #设置图例
    
    # 添加数据标签
    def autolabel(rects):
        for rect in rects:
            height = rect.get_height()
            if height>0:
                ax.annotate('{}'.format(height),
                        xy=(rect.get_x() + rect.get_width() / 2, height),
                        xytext=(0, 3),  # 3 points vertical offset
                        textcoords="offset points",
                        ha='center', va='bottom')
            else:
                ax.annotate('{}'.format(height),
                        xy=(rect.get_x() + rect.get_width() / 2, height),
                        xytext=(0, -13),  # 3 points vertical offset
                        textcoords="offset points",
                        ha='center', va='bottom')
    autolabel(rects1)
    autolabel(rects2)
    fig.tight_layout()
    #保存图片  
    #plt.savefig(r'E:\Data_resourses\DataCharm 公众号\Python\学术图表绘制\barplot05.png',dpi=600,bbox_inches = 'tight')
    
    • 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

    在这里插入图片描述

    2.2 两组数据堆叠绘制

    import numpy as np
    import matplotlib.pyplot as plt
    
    
    # 数据代表一年12个月小明和小刚的智商(纯属捏造)
    x = [i for i in range(1,13)]
    xiaoming = [111,124,101,132,127,114,140,135,104,120,101,118]
    xiaogang = [132,142,121,101,114,135,126,116,105,131,97,102]
    
    #plt.rcParams['font.sans-serif'] = ['SimHei']
    
    plt.rcParams['font.family'] = ['Times New Roman']
    fig,ax = plt.subplots(1,1,figsize=(7,4.5),dpi=200)
    width = 0.35  # 柱子宽度
    
    #字体设置
    label_font = {
        'weight':'bold',
        'size':14,
        'family':'SimHei'
    }
    legend_font = {
        'weight':'bold',
        'size':10,
        'family':'SimHei'
    }
    
    rects1 = ax.bar(x, height = xiaoming, width = width ,ec='k',color='white',  
                    lw=.8, label = "小明", hatch='//')
    rects2 = ax.bar(x, height = xiaogang, width = width ,ec='k',color='white',  
                    lw=.8, label = "小刚", hatch='xxxxxx',bottom = xiaoming)
    
    ax.tick_params(axis='x',direction='out',length=5,width=1.5,labelsize=11,bottom=True)#x轴刻度设置
    ax.set_xlabel('月份',fontdict=label_font) #x轴名称
    #set_xticks(x)和set_xticklabels(x)一般一起使用
    ax.set_xticks(x) #设置显示刻度标签的位置,最好与ax.bar的第一个参数一致
    ax.set_xticklabels(x)#设置刻度值对应的标签,可以是字符串型
    
    ax.tick_params(axis='y',direction='out',length=5,width=1.5,labelsize=11,bottom=False) #y轴刻度设置
    ax.set_ylabel('智商',fontdict=label_font) #y轴名称
    ax.set_ylim(ymin = 90,ymax = 300) #y轴刻度范围
    ax.set_yticks(np.arange(90,301,50)) #设置显示刻度标签的位置
    ax.set_yticklabels(np.arange(90,301,50))#设置刻度值对应的标签,可以是字符串型
    
    ax.axhline(0, color='black',alpha=0.5) #绘制y=0的线
    ax.legend(loc='best',markerscale=8,fontsize=10,prop=legend_font) #设置图例
    
    # 添加数据标签
    def autolabel(rects1,rects2):
        for i in range(len(rects1)):
            rect1 = rects1[i]
            rect2 = rects2[i]
            height = rect1.get_height()+rect2.get_height()
            if height>0:
                ax.annotate('{}'.format(height),
                        xy=(rect2.get_x() + rect2.get_width() / 2, height),
                        xytext=(0, 3),  # 3 points vertical offset
                        textcoords="offset points",
                        ha='center', va='bottom')
            else:
                ax.annotate('{}'.format(height),
                        xy=(rect2.get_x() + rect2.get_width() / 2, height),
                        xytext=(0, -13),  # 3 points vertical offset
                        textcoords="offset points",
                        ha='center', va='bottom')
    autolabel(rects1,rects2)
    fig.tight_layout()
    #保存图片  
    #plt.savefig(r'E:\Data_resourses\DataCharm 公众号\Python\学术图表绘制\barplot05.png',dpi=600,bbox_inches = 'tight')
    
    • 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

    在这里插入图片描述

    ax.bar函数中设置 bottom参数 ,表示数据从哪个数开始绘制,该参数的长度应该与将绘制数据的长度相同。

    在此案例中,我设置第二个柱形图的bottom为第一个柱形图的数据,表示第二个柱形图堆叠在第一个柱形图上绘制。若有第三个柱形图想要堆在第二个柱形图上,则需要将前两个柱形图的值相加,可以用如下表达式:[x + y for x, y in zip(xiaoming, xiaogang)],第四个、第五个以此类推。

  • 相关阅读:
    谷粒商城 (十三) --------- 商品服务 API 三级分类 ④ 删除、新增分类
    【学习笔记】C++并发与多线程笔记五:unique_lock详解
    Java--请求转发;重定向;异常处理;拦截器
    【C++】类和对象——下
    mysql-视图/存储过程/触发器
    spark withColumn的使用(笔记)
    自动驾驶框架:自动驾驶汽车定位-感知-规划-决策-控制概述,按照我的架构图理解:决策决定的是速度,规划决定的是路径(架构理解推荐)
    flutter百度地图定位, poi检索功能
    JAVA接入OPC DA2.0详细流程
    EdgeX Foundry 边缘物联网中间件平台
  • 原文地址:https://blog.csdn.net/cyj972628089/article/details/126367474