本节提要:前面已经陆陆续续有一些关于这三类的讲解,但是分散在各章中,不太方便大家查找,所以加强版做了这一期合集,来方便大家使用。
一、轴坐标名
这一节主要讲解图的坐标名的设置方法、常用的美化命令。
首先是设置坐标名称的命令【plt.xlabel (ylabel) 】或者【ax.set_xlabel (ylabel)】
在其中以引号输入你需要的标题文本,如:
ax.set_xlabel('x轴的名称')
这样就会生成x轴坐标名,y轴同理。当然,大多数时候这个最质朴的命令是无法满足我们的需求的。由于该命令完全是基于text模块的,所以他能使用text模块的关键字参数。下面列举了一些常用的设置关键字参数:
fontsize |
修改文本的字号(大小) |
alpha |
修改文本的透明度 |
backgroundcolor |
背景颜色 |
bbox |
给标签加上多种样式的边框 |
color |
标签文本的颜色 |
family |
字体的样式,如黑体、仿宋、楷体等 |
ha、va |
横向、纵向的位置,如center、left |
rotation |
文本旋转的角度,一般用数字来控制 |
position |
标签的位置,(x,y)样式传入 |
loc |
控制标签的位置,‘top’,‘left’等 |
下面这幅图使用了一些参数,需要注意的是bbox这个参数需要以字典的方式附带一些方框的参数(这个字典里的参数只控制这个方框的样式)。当然你也可以将这些参数进一步写到字典里,在下面程序段中,最后一个语句和第一个语句效果是一样的:
ax.set_xlabel('批次',color='k',backgroundcolor='tab:blue',rotation=45)
ax.set_ylabel('产量',color='tab:orange',fontsize=20,
position=(0,0.225),family='FangSong',
bbox={'facecolor':'none','lw':2,'ls':'-.','edgecolor':'k'})
ax.set_xlabel('批次',fontdict={'color':'k',
'backgroundcolor':'tab:blue','rotation':45})
二、刻度
刻度基本上绘制一幅图就要手动设置,因为matplotlib默认的刻度样式是比较丑的,我们的美化教程从刻度的生成开始。
首先介绍刻度默认的生成位置,由于大部分人的读图习惯,横纵轴的刻度一般是默认左-下分布,即横轴刻度在下,纵轴刻度在左。不过,某些时刻,我们一定要修改其位置,怎么做呢?有两个简单的办法:
ax.xaxis.tick_top( )#或者
ax.xaxis.set_ticks_position('top')
下面这张图以不同方式修改了刻度显示的位置:
ax1.xaxis.tick_top()
ax2.xaxis.set_ticks_position('top')
ax3.yaxis.set_ticks_position('right')
接下来又有问题了,如果我想四边都要显示刻度怎么办呢?也有一个简单的命令:
ax1.tick_params(top=True,bottom=True,left=True,right=True)
那么,如何使刻度不显示呢?在设置刻度命令时传入空列表即可:
ax.set_xticks([ ])
ax.set_yticks([ ])
这样就使四个边都显示出了刻度。接下来,我们学习修改刻度的样式。就比方说上面这个ax1,很明显,无论是刻度的长度宽度还是刻度标签都偏大、偏粗。matplotlib里有一个常用的调节刻度样式的命令——ax.tick_params( )。下面简要列举了一些常用参数:
axis |
指定要修改的轴,如'x','y','both' |
which |
要修改的主副刻度,如'major''minor''both' |
direction |
刻度的小齿的方向,如'in''out' |
length |
刻度小齿的长度 |
width |
刻度小齿的宽度 |
color |
刻度小齿的颜色 |
pad |
刻度标签与刻度小齿的距离 |
labelsize |
刻度标签字体的大小 |
labelcolor |
刻度标签字体的颜色 |
rotation | 旋转刻度标签 |
我们通过一个简单的图片来操作这个命令:
ax.tick_params(axis='x',which='major',direction='in',
width=2,color='tab:orange',labelcolor='tab:blue',labelsize=5)
ax.tick_params(axis='y',which='major',direction='in',
width=0.5,length=2,labelsize=5,pad=20,rotation=45)
学习完了修改刻度的样式,接下来就是非常实用的刻度值的修改了。刻度值关系到我们绘制出来的成品的效果,一图抵千言的前提是你的图片的质量合格,突显了你需要讲明的内容,而忽略一些在当前语境下不重要的内容。比如,一张连续性的,整体值偏大的数据:
上面这张的刻度值是系统随机生成的,下面这张是经过修饰的,哪一张更能抓住要点、捕获眼球呢?毫无疑问第二张图胜出了,固然其不能展示从0-2000的形势,但我们的分析本来也不需要从0开始。另外我们需要集中展示某一个区间或特定值的样式,默认的刻度也不能完成我们的需求,显然也要另加命令以做调整。
首先,是限制刻度值范围:
ax.set_xlim(10,20)#横轴只会显示10-20范围
ax.set_ylim(100,500)#纵轴只会显示100-500范围
一般来说,刻度值都是从小到大的,我们还可以颠倒其走向:
ax.set_xlim(20,10)#横轴从20开始走到10
ax.invert_xaxis( )#也是颠倒方向,但是不能限定范围
某些时候,我们需要让刻度显示的比较特殊,这个时候可以通过改设刻度命令实现,这时仅会显示出我们设定的刻度:
ax.set_xticks([0.1,0.2,0.3,0.55])
在某些时候,我们不需要数值,而是数值对应的某个表征量,如分数在90-100是优秀,累计降雨量在250毫米以上是特大暴雨。这个时候不再需要理性的数字,而是感性的描述性文字,通过如下命令,即可完成替换,替换的内容可以是各种形式的。但是请注意,pandas等是支持时间格式的,时间格式可以直接标注在坐标上,所以不要使用x=range(1,20),然后再用下面的命令改为时间格式的笨办法:
ax.set_yticks([0.1,0.2,0.55,0.9])
ax.set_yticklabels(['一般般','挺不错','映象深刻','非常好'])
除了ax.tick_params( )语句外,在axisartist下生成的子图,还可以用ax.axis[ ]语句改变刻度的样式(常用的fig.add_axes(),subplot()生成的子图无法使用)。
ax.axis['left'].set_axis_direction('right')#使纵坐标放在右边
ax.axis['bottom'].set_axis_direction('top')#使横坐标放在上边
ax.axis[:].major_ticks.set_tick_out(True)#使刻度向外
ax.axis['left'].label.set_text('纵轴标签名')
ax.axis['left'].label.set_pad(0)#调节标签与轴的距离
最后,进入关键的刻度格式环节,这个环节是颇为重要的,可以省去很多力气。刻度格式生成器和刻度样式生成器是两个非常重要的模块。当然,其最强大的样式生成部分,我们多数时候只能用到经纬度标签这种,其实的比如金融、数学、物理等部分我们很少使用,也不多介绍。
在matplotlib的ticker模块中,提供了专门的刻度格式化命令。首先导入库包:
import matplotlib.ticker as mticker
首先使用刻度格式生成器,这个命令需要调用ax.xaxis.set。
一。无刻度格式(Nulllocator)
顾名思义,这个会使轴上面没有刻度显示。
ax.yaxis.set_major_locator(mticker.NullLocator())
二。等距刻度命令(MultipleLocator)
在这个命令下,刻度将会等距均匀分布。
ax.yaxis.set_major_locator(mticker.MultipleLocator(0.25))
三。抑制刻度数量命令(MaxNLocator)
在这个命令下,轴上的刻度将被限制在你设定的数量之下,剩下的刻度将会均匀分布。
ax.xaxis.set_major_locator(mticker.MaxNLocator(5))
ax.yaxis.set_major_locator(mticker.MaxNLocator(2))
横轴除开零刻度只有五个刻度,纵轴除开0刻度只有两个。
4.均匀刻度命令(LinearLocator)
该命令使刻度按划分数量均匀显示。
ax.yaxis.set_major_locator(mticker.LinearLocator(10))
5.刻度固定(FixedLocator)
在该命令下,只会显示固定的刻度,即你指定要显示哪些刻度,其余的不显示。
ax.yaxis.set_major_locator(mticker.FixedLocator(np.arange(0,0.71,0.1)))
ax.yaxis.set_major_locator(mticker.FixedLocator([0,0.1,0.2,0.3,0.4,0.5,0.6,0.7]))
然后,进入到实用的刻度样式环节。前面已经说过,经纬度是我们最常用的刻度样式,目前在绘制地图时,有两种常用的方法——一种是通过魔改matplotlib实现,一种是通过cartopy里的gridlines实现。
先讲魔改matplotlib的,这种实际上就是将子图坐标样式修改为经纬度,这种以后还可以用ax.tick_params( )来修改刻度的艺术样式。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as mticker
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from cartopy.mpl.ticker import LongitudeFormatter,LatitudeFormatter
plt.rcParams['font.sans-serif']=['SimHei']#中文
extent=[108.3,109.35,29.7,30.7]
reader = shpreader.Reader(r'E:\家园\利川市地图\利川.shp')
fig=plt.figure(figsize=(4.5,2),dpi=700)
#######添加两个子图###################
ax1=fig.add_axes([0,0,0.5,1],projection=ccrs.PlateCarree())
ax2=fig.add_axes([0.55,0,0.5,1],projection=ccrs.PlateCarree())
######子图1的修饰##########################
ax1.add_geometries(reader.geometries(),crs=ccrs.PlateCarree(),lw=0.5,edgecolor='k')
ax1.set_extent(extent)
ax1.set_xticks([108.5,108.73,108.94,109.15,109.349])
ax1.set_yticks(np.arange(extent[2], extent[3]+0.2, 0.2))
ax1.xaxis.set_major_formatter(LongitudeFormatter())
ax1.yaxis.set_major_formatter(LatitudeFormatter())
ax1.tick_params(axis='both',labelsize=5,direction='in')
ax1.grid(linewidth=0.6, color='k', alpha=0.45, linestyle='--')
ax1.set_title('通过魔改matplotlib的方式')
######子图2的修饰##########################
ax2.add_geometries(reader.geometries(),crs=ccrs.PlateCarree(),lw=0.5,edgecolor='k')
ax2.set_extent(extent)
gl = ax2.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,linewidth=0.6, color='k', alpha=0.45, linestyle='--')
gl.xlabels_top = False
gl.ylabels_left = False
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
gl.xlocator = mticker.FixedLocator([108.3,108.5,108.73,108.94,109.15,109.349,109.5])
gl.ylocator = mticker.FixedLocator(np.arange(extent[2], extent[3]+0.2, 0.2))
gl.xlabel_style={'size':5}#修改经纬度字体大小
gl.ylabel_style={'size':5}
ax2.set_title('通过gridlines方式')
plt.show()
gridlines方式设置比较简便,但是目前我好像没发现他能调出小刻度齿,经纬度线直接连接到边框。魔改matplotlib方式基于axis方式,只要能掌握前面提到的那些命令,修饰语句更多,还有经纬度的小刻度齿。常规使用我推荐gridlines语句,如果还需要修饰美化,就推荐魔改方式。
当然,这里都只是涉及到PlateCarree投影方式。目前0.17版本的cartopy是没办法在其他投影中使用gridlines来绘制经纬度标签的。
三、边框(轴)
边框(轴)是子图中比较重要的一部分,下面简要介绍一些实用的边框操作。
A、边框的隐现
对普通的子图
ax.axis('off')#该命令使全部框线和刻度消失
对地图
ax.background_patch.set_visible(False) #使框线全部消失
ax.outline_patch.set_visible(False)
对普通的子图,仅对某一边或几边去框线
ax.spines['top'].set_linewidth(0)#框线宽度为0,则在视觉效果上为无框线
ax.spines['right'].set_color('None')#框线无颜色,在在视觉效果上为无框
对地图
ax1.outline_patch.set_visible(False)#关闭GeoAxes框线
ax1.spines['left'].set_visible(True)#开启Axes框线
ax1.spines['left'].set_linewidth(0)#框线宽度为0,则在视觉效果上为无框线
B、边框的粗细
参考上一节的关于边框粗细语句。
C、坐标轴仅显示一部分
ax.spines['top'].set_linewidth(0)
ax.spines['right'].set_linewidth(0)
ax.spines['left'].set_bounds(-10,10)
ax.yaxis.set_major_locator(mticker.FixedLocator([-10,0,10]))
ax.spines['bottom'].set_bounds(0,50)
D、使坐标轴和子图内容物有一定的距离
ax.spines['left'].set_position(('outward',10))
ax.spines['bottom'].set_position(('outward',10))
E、使轴生成箭头
import matplotlib.pyplot as plt
import mpl_toolkits.axisartist as axisartist
def setup_axes(fig, rect):
ax = axisartist.Subplot(fig, rect)
fig.add_axes(ax)
ax.set_ylim(-0.1, 1.5)
ax.set_yticks([0, 1])
ax.axis[:].set_visible(False)
ax.axis["x"] = ax.new_floating_axis(1, 0.5)
ax.axis["x"].set_axisline_style("->", size=1.5)
return ax
fig = plt.figure(figsize=(3, 2.5),dpi=200)
fig.subplots_adjust(top=0.8)
ax1 = setup_axes(fig, "111")
ax1.axis["x"].set_axis_direction("left")
plt.show()
四、在色标中运用刻度与轴的知识
色标是等值线填色图中最重要的一部分,很多时候需要进一步设置使图像美观,现在就这章内容进行联系讲解。
通过下面语句在色标内调用刻度命令:
cb=fig.colorbar(......)
cb.ax.tick_params( )
这样就进入到上面提到的流程,只要在括号中修改参数即可。
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np
fig=plt.figure(figsize=(2,1),dpi=500)
cmap=mpl.cm.viridis
norm=mpl.colors.Normalize(vmin=6.0,vmax=9)
position=plt.axes([0.,0.,1,0.1])
cb=fig.colorbar(mpl.cm.ScalarMappable(norm=norm,cmap=cmap),cax=position,
extend='both',shrink=0.4,label='label气温标题',orientation='horizontal')
cb.ax.set_title('title气温标题',fontsize=11)
cb.ax.tick_params(axis='both',which='major',direction='in',labelsize=7,length=7.4,width=0.5)
plt.show()
如何设置色条外框的粗?通过下面这个语句修改:
cb=fig.colorbar(......)
cb.outline.set_linewidth(0.1)
谢谢阅读!
本文分享自微信公众号 - 气象学家(Meteorologist2019)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/4579644/blog/4493502