专栏首页气象学家Python-matplotlib 学术柱状图绘制

Python-matplotlib 学术柱状图绘制

01. 引言

柱状图或条形图在学术论文中使用的频率还是很大的,图中需要以不同颜色对不同数据进行区分,但当涉及黑白打印时,色彩颜色的区别度较小,导致难以理解,因此需要绘制黑灰颜色或者黑白阴影的柱状图或者条形图,下面就具体介绍使用Python-matplotlib 的实现过程。

02. 可视化绘制

matplotlib绘制这种柱状图或者条形图还是比较简单的,主要涉及的知识点就是ax.bar()方法的应用,首先进行黑灰颜色柱状图的绘制,具体代码如下:

plt.rcParams['font.family'] = ['Times New Roman']
fig,ax = plt.subplots(1,1,figsize=(7,4.5),dpi=200)
labels = [i for i in bar_01.columns[2:]]
x = np.arange(len(labels))  # the label locations
width = 0.35  # the width of the bars

label_font = {
    'weight':'bold',
    'size':14,
    'family':'simsun'
}

rects1 = ax.bar(x - width/2, means_2006, width, label='2006',ec='k',color='white',lw=.8
               )
rects2 = ax.bar(x + width/2 + .05, means_2016, width, label='2016',ec='k',color='white',
                lw=.8)
# rects2 = ax.bar(x + width/2 + .05, means_2016, width, label='2016',ec='k',color='k',
#                 lw=.8,alpha=.8)
ax.tick_params(which='major',direction='in',length=5,width=1.5,labelsize=11,bottom=False)
ax.tick_params(axis='x',labelsize=11,bottom=False,labelrotation=15)
ax.set_xticks(x)
ax.set_ylim(ymin = 0,ymax = 1800)
ax.set_yticks(np.arange(0,1900,200))

ax.set_ylabel('(亿元)',fontdict=label_font)
ax.set_xticklabels(labels,fontdict=label_font)
#ax.legend(markerscale=10,fontsize=12,prop=legend_font)
ax.legend(markerscale=10,fontsize=12)

# Add some text for labels, title and custom x-axis tick labels, etc.
def autolabel(rects):
    for rect in rects:
        height = rect.get_height()
        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')
autolabel(rects1)
autolabel(rects2)
fig.tight_layout()
plt.savefig(r'E:\Data_resourses\DataCharm 公众号\Python\学术图表绘制\barplot05.png',dpi=600,bbox_inches = 'tight')

其中的labels、means_2006和means_2016 的值具体如下:

labels = ['生产总值', '第一产业增值', '第二产业增值', '第三产业增值', '工业增值', '建筑业增值']
means_2006 = [494.19, 94.38, 208.92, 190.89, 172.2, 36.72]
means_2016 = [1531.2, 192, 727.2, 612, 670.79, 87.5]

制作效果如下:

如果大家觉得图的轴脊(spines)比较细,也可以通过如下代码进行更改:

linewidth = 2
for spine in ['top','bottom','left','right']:
    ax.spines[spine].set_linewidth(linewidth)

可以看到x轴的标签进行了自定义设置,同时也进行部分旋转,代码如下:

#设置坐标轴选旋转labelrotation=15
ax.tick_params(axis='x',labelsize=11,bottom=False,labelrotation=15)
#自定义x坐标轴标签
ax.set_xticks(x)

这里使用了中文宋体,字体的调用也比较简单,详细可以查看代码,或者看我之前的文章Python-matplotlib 学术散点图完善。

上述的图表对一般的期刊图表要求基本可以满足,打印时的效果也还不错。当然也可以使用纹理填充,涉及的主要参数为hatch 属性设置。主要绘图代码如下:

rects1 = ax.bar(x - width/2, means_2006, width, label='2006',ec='k',color='white',lw=.8,
               hatch='...')
rects2 = ax.bar(x + width/2 + .05, means_2016, width, label='2016',ec='k',color='white',
                lw=.8,hatch='***')

这里color设置为'white',边框颜色(edgecolor,ec)设置为'k'黑色,同时设置线宽lw=0.8,最后设置hatch 参数。结果如下:

可接受的类型如下:

如果需要让图案更加密集,可以多输入‘......’或者‘//////’,具体的密度根据自己的绘图需求进行调整。需要注意的时,如果输入‘\’,则需要进行转义处理,即输入'\\'。下面绘制不同填充纹理,结果如下:

rects1 = ax.bar(x - width/2, means_2006, width, label='2006',ec='k',color='white',lw=.8,
               hatch='.....')
rects2 = ax.bar(x + width/2 + .05, means_2016, width, label='2016',ec='k',color='white',
                lw=.8,hatch='//////')
rects1 = ax.bar(x - width/2, means_2006, width, label='2006',ec='k',color='white',lw=.8,
               hatch='----')
rects2 = ax.bar(x + width/2 + .05, means_2016, width, label='2016',ec='k',color='white',
                lw=.8,hatch='+++++')
rects1 = ax.bar(x - width/2, means_2006, width, label='2006',ec='k',color='white',lw=.8,
               hatch='xxxx')
rects2 = ax.bar(x + width/2 + .05, means_2016, width, label='2016',ec='k',color='white',
                lw=.8,hatch='oooo')
rects1 = ax.bar(x - width/2, means_2006, width, label='2006',ec='k',color='white',lw=.8,
               hatch='||||')
rects2 = ax.bar(x + width/2 + .05, means_2016, width, label='2016',ec='k',color='white',
                lw=.8,hatch='***')

统计直方图hist绘制

部分论文中出现对一组数据进行统计不同区间内的数据个数,这就需要绘制统计直方图,下面就进行此图的绘制,所使用的方法为plt 方法绘制,具体代码如下:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt 

from matplotlib.ticker import MultipleLocator, FormatStrFormatter
plt.figure(figsize=(10,7))

bins = np.arange(0.0,1.6,0.1)

plt.hist(x=Nov_2017_data.values, bins=bins,color="#3F3F3F",alpha=0.85,edgecolor ='black',rwidth = 0.75)#,
        #align = 'center')
plt.xticks(np.arange(0,1.7,0.1))
plt.yticks(np.arange(0.,1400,100))
plt.xlim(0.0,1.6)
plt.ylim(0.0,1300)

xminorLocator = MultipleLocator(0.05) #将x轴次刻度标签设置为0.05的倍数
yminorLocator = MultipleLocator(50) #将此y轴次刻度标签设置为50的倍数
ax=plt.gca()
#设置次刻度标签的位置,没有标签文本格式
ax.xaxis.set_minor_locator(xminorLocator)
ax.yaxis.set_minor_locator(yminorLocator)

#设置边框显示与否
ax.tick_params(direction='out',width=1.5,length=5,labelsize = 16) #默认为主刻度线
ax.tick_params(which = 'minor',width = 1.1,length = 3.5)
# 设置坐标刻度值的大小以及刻度值的字体
#plt.tick_params(labelsize=23)
labels = ax.get_xticklabels() + ax.get_yticklabels()
[label.set_fontname('Times New Roman') for label in labels]


bwith =1.3
# ax.spines['top'].set_color('red')  # 设置上‘脊梁’为红色
# ax.spines['right'].set_color('none')  # 设置上‘脊梁’为无色

#去掉边框
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# ax.spines['bottom'].set_visible(False)
# ax.spines['left'].set_visible(False)

ax.spines['bottom'].set_linewidth(bwith)
ax.spines['left'].set_linewidth(bwith)
# ax.spines['top'].set_linewidth(bwith)
# ax.spines['right'].set_linewidth(bwith)

# 设置横纵坐标的名称以及对应字体格式
font1 = {'family': 'Times New Roman',
         'weight': 'extra bold',
         'size': 25,
         }
plt.xlabel('Values', font1)
plt.ylabel('Number of cases', font1)
#添加文本
plt.text(0.52,.9,'Period:November 2017',transform=ax.transAxes,
         fontdict={'size': 23,'family': 'Times New Roman','weight': 'extra bold'})
plt.savefig(r"P:\DataCharm\学术图标绘制\hist.png",width=10,height = 7,dpi=900,bbox_inches='tight')
plt.show()

主要涉及主次刻度及标签的设置,主要使用plt 方法绘制。结果如下:

03. R patternplot

相对于Python-matplotlib 绘制填充纹理而言,R-patternplot 包则可以更加灵活方便的绘制各种类型图表的填充样式。patternplot软件包是用于在R中创建美观且内容丰富的饼图,环形图,条形图和箱形图的工具。它可以用颜色或纹理或png中的任何外部图像填充饼图,环形图,条形图和箱形图或jpeg格式。下面列举几个图表案例,具体内容可以参考网址:https://cran.rproject.org/web/packages/patternplot/vignettes/patternplot-intro.html

library(patternplot)
library(png)
library(ggplot2)
data <- read.csv(system.file("extdata", "vegetables.csv", package="patternplot"))
#Example 1
pattern.type<-c('hdashes', 'vdashes', 'bricks')
pie1<-patternpie(group=data$group,pct=data$pct,label=data$label, 
                 label.size=4, label.color='black',label.distance=1.3,pattern.type=pattern.type,
           pattern.line.size=c(10, 10, 2), frame.color='black',frame.size=1.5, pixel=12, density=c(8, 8, 10))
pie1<-pie1+ggtitle('(A) Black and White with Patterns')
#Example 2
pattern.color<-c('red3','green3', 'white' )
background.color<-c('dodgerblue', 'lightpink', 'orange')
pie2<-patternpie(group=data$group,pct=data$pct,label=data$label, label.distance=1.3, pattern.type=pattern.type,
           pattern.color=pattern.color,background.color=background.color, 
           pattern.line.size=c(10, 10, 2), frame.color='grey40',frame.size=1.5, pixel=12, density=c(8, 8, 10))
pie2<-pie2+ggtitle('(B) Colors with Patterns')

library(gridExtra)
grid.arrange(pie1,pie2,  nrow = 1)

当然也可以以图片为底纹理:

library(patternplot)
library(ggplot2)
library(jpeg)
Tomatoes <-  readJPEG(system.file("img", "tomatoes.jpg", package="patternplot"))
Peas <- readJPEG(system.file("img", "peas.jpg", package="patternplot"))
Potatoes <-  readJPEG(system.file("img", "potatoes.jpg", package="patternplot"))

#Example 1
data <- read.csv(system.file("extdata", "vegetables.csv", package="patternplot"))
pattern.type<-list(Tomatoes,Peas,Potatoes)
imagepie(group=data$group,pct=data$pct,label=data$label,pattern.type=pattern.type,
         label.distance=1.3,frame.color='burlywood4', frame.size=0.8, label.size=6,
         label.color='forestgreen')+ggtitle('Pie Chart with Images')

还有其他样式:

更多案例,大家可以自己去官网进行查看。

04. 总结

python-matplotlib绘制纹理填充的学术性柱状图以及统计直方图绘制过程整体上不难,主要还是细节设置,此外,本推文也使用 plt 方法进行绘制。同时也可以看到 R 在绘制图表上的功能完善性(有各种拓展包用于不同类型图表绘制),如绘制纹理填充方面,patternplot包 就非常实用。学术图表绘制需要准备较多的素材数据,更新难免有所缓慢,但会坚持下去。自己能力有限,难免会有出错,如发现可以后台留言或进群讨论。

本文分享自微信公众号 - 气象学家(Meteorologist2019)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 气象人开发的高级科学绘图库Proplot!

    Proplot对matplotlib进行了高度的封装,是一个高级绘图工具,其功能相当强大!而且融和了cartopy、basemap、xarray和pandas。...

    气象学家
  • Python绘制日历图和热力图

    本文以2019年全国各城市的空气质量观测数据为例,利用matplotlib、calmap、pyecharts绘制日历图和热力图。在绘图之前先利用pandas对空...

    气象学家
  • Python-matplotlib 学术散点图完善

    上期的推文Python-matplotlib 学术型散点图绘制 推出后,很多小伙伴比较喜欢

    气象学家
  • 3D可视化应用开发(webgl方向)到底有多难?

    作为一个前端开发工程师,你是不是已经习惯了敲代码,写页面,修BUG,这一点毫无争议,这是工作性质决定的,就像运动员每天都要高强度训练一样。

    要不要吃火锅
  • Django 2.1.7 视图

    上一篇中讲诉了Django关于模型的设计以及数据操作,本篇章就来继续讲解关于模板的内容。

    Devops海洋的渔夫
  • go笔记:go语言中使用协程异步并行

    超级大猪
  • Knockout.Js官网学习(event绑定、submit绑定)

    event绑定在DOM元素上添加指定的事件句柄以便元素被触发的时候执行定义的JavaScript 函数。大部分情况下是用在keypress,mouseover和...

    aehyok
  • python图片验证码识别最新模块muggle_ocr的示例代码

    黑科技?还是黑代码? 我感觉这个看在你用啥,对不对?反正我用来(* * * * ) 你懂得

    砸漏
  • 如何关闭SAP Fiori的病毒扫描设

    版权声明:本文为博主汪子熙原创文章,未经博主允许不得转载。 https://jerry.bl...

    Jerry Wang
  • 看了这篇,关于浏览器缓存你还有哪些疑问?

    【转载请注明出处】:https://blog.csdn.net/huahao1989/article/details/107730210

    后端老鸟

扫码关注云+社区

领取腾讯云代金券