如何自定义横纵坐标刻度?以及如何指定横纵坐标的格式?

如何自定义横纵坐标刻度值?以及如何指定横纵坐标的格式?

可能有些同学在画图的过程中会遇到这样的问题:

  • 需要画某个物理量随时间的变化,但是横坐标显示的却是一个个自然数?或者横坐标虽然是datatime时间格式,但是在图中的显示却不是自己想要的,这个时候就需要我们手动调整坐标刻度的值;

  • 在画多张子图的时候,共用同一个横坐标,这个时候为了美观需要只保持最下方子图的横坐标,上面子图的横坐标只显示刻度,不显示值;

下面让我们来看看如何解决这两个问题。事实上这两个问题只需要两行代码即可解决:

ax.set_xticks(...)  # 设置显示哪些刻度(不是刻度值)
ax.set_xticklabels(..., fontdict=font)  # 设置所显示的刻度对应的刻度值,另外fontdict参数可设置刻度值的属性
# 第二行指令依赖于第一行指令,刻度与刻度值需要一一对应,否则会出现刻度与值对应不上的情况

1. 在第一个问题中,我有一天24小时每半小时一个值的表面温度数据,需要绘制表面温度的日变化图。

问题分析:现在有48个点,但是横坐标不需要标出所有48个值,我只想显示[‘01:30’, ‘05:30’, ‘09:30’, ‘13:30’, ‘15:30’, ‘21:30’]对应的刻度。

step1 确定[‘01:30’, ‘05:30’, ‘09:30’, ‘13:30’, ‘15:30’, ‘21:30’]所对应的是第几个点。在此问题中24小时每半小时一个数据,所有分别对应第[3, 11, 19, 27, 35, 43]个点;

step2 向上面两行代码中添加对应参数;

import matplotlib.pyplot as plt

# 创建空白画布
fig = plt.figure(figsize=(8, 5))
# 在空白画布中创建绘图框(绘图对象)
ax = fig.add_subplot(1, 1, 1)
# 绘图
ax.plot(...)
...(其他步骤省略,这里只显示关键步骤)
# 注意ax是绘图对象
ax.set_xticks([3, 11, 19, 27, 35, 43])  # 或者ax.set_xticks(np.arange(3, 49, 8))
ax.set_xticklabels(['01:30', '05:30', '09:30', '13:30', '15:30', '21:30'])  # 设置刻度值

2. 有了第一个问题的基础,第二个问题就很简单了。

问题分析:多子图时,不显示重复的刻度值,但是仍然标注除刻度。

step1 仍然先找出需要标注的刻度位置,即对应的第几个点;

step2 将挑出刻度的刻度值设置为空;

ax.set_xticks([3, 11, 19, 27, 35, 43])  # 或者ax.set_xticks(np.arange(3, 49, 8))
ax.set_xticklabels([])

3. 我们都知道一般不同的期刊对paper中的图的要求也不一样,可能会对图中字体、大小等属性进行要求,这个时候就需要用到fontdict参数。

# 设置字体格式
font = {'family': 'Times New Roman',  # 设置字体格式
        #'style': 'italic',  # 修改倾斜程度
        'weight': 'normal',  # 修改粗细
        'color': 'black',  # 颜色
        'size': 15,  # 字体大小
        }  # 设置xlabel、title、text等字体设置

ax.set_xticks([3, 11, 19, 27, 35, 43])  # 或者ax.set_xticks(np.arange(3, 49, 8))
ax.set_xticklabels(['01:30', '05:30', '09:30', '13:30', '15:30', '21:30'], fontdict=font)

注意: 如果想要对刻度值设置字体属性,set_xticksset_xticklabels都需要,应该先挑出想要修改字体属性的点,再进行设置。

程序部分源码分享(略去了数据处理部分):

第一张图主要绘图代码:plot()部分根据实际情况修改;

import numpy as np
import matplotlib.pyploy as plt

# 设置字体格式
font = {'family': 'Times New Roman',  # 设置字体格式
        #'style': 'italic',  # 修改倾斜程度
        'weight': 'normal',  # 修改粗细
        'color': 'black',  # 颜色
        'size': 15,  # 字体大小
        }  # 设置xlabel、title、text等字体设置

fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(1, 1, 1)
# # paint
ax.plot(paint_day.mean(axis=0), label='paint')  # 平均
ax.fill_between(paint_day.mean(axis=0).index, paint_day.mean(axis=0) + paint_day.std(axis=0), paint_day.mean(axis=0) - paint_day.std(axis=0), alpha=.2, linewidth=0, label=r'${\rm +/-STD_{paint}}$')  # 加减标准差,阴影图

# 设置y轴刻度的范围
ax.set_ylim((-5, 47))
ax.set_yticks(np.arange(0, 45, 10))
ax.set_yticklabels(np.arange(0, 45, 10), fontdict=font)
# 设置x轴刻度的范围
ax.set_xlim((0, 47))
ax.set_xticks(np.arange(3, 49, 8))
ax.set_xticklabels(['01:30', '05:30', '09:30', '13:30', '15:30', '21:30'], fontdict=font)
# 设置坐标标题
ax.set_ylabel('Cooling efficiency(%)', fontdict=font)
# 设置标题
ax.set_title('The daily cooling efficiency', fontdict=font)
# 设置图例
plt.legend(loc='upper left', ncol=2, fontsize=7)

第二张图主要绘图代码:plot()部分根据实际情况修改;

import numpy as np
import matplotlib.pyploy as plt

# 设置字体格式
font = {'family': 'Times New Roman',  # 设置字体格式
        #'style': 'italic',  # 修改倾斜程度
        'weight': 'normal',  # 修改粗细
        'color': 'black',  # 颜色
        'size': 12,  # 字体大小
        }  # 设置xlabel、title、text等字体设置

fig = plt.figure(figsize=(10, 5), dpi=300)
# # 绘图散点图
ax = fig.add_subplot(2, 1, 1)
ax.scatter(roof_1d.index, roof_1d['3sigma_albedo'], s=5, label='roof')
ax.scatter(tpo_1d.index, tpo_1d['3sigma_albedo'], s=5, label='tpo')
ax.scatter(aa_1d.index, aa_1d['3sigma_albedo'], s=5, label='aa')
# 纵坐标刻度和标签
ax.set_ylabel('Albedo', fontdict=font)
ax.set_ylim((0, 1))
ax.set_yticks([0, 0.25, 0.5, 0.75])
ax.set_yticklabels([0, 0.25, 0.5, 0.75], fontdict=font)
# 设置文本标签(a),注意:在这里绘图的时候x为datatime时间格式,所以text()中的横坐标也需要用时间格式(直接用字符串'2017-02'也是可以的)
ax.text(datetime.strptime('2017-02', '%Y-%m'), 0.9, '(a)', fontdict=font)

# 不显示横坐标标签,但是显示刻度
# 生成月份
month = [(i-8) % 12 for i in range(43)]
for i in range(len(month)):
    if month[i] == 0:
        month[i] = 12
month = month[::2]
# 生成年份
year = []
for i in range(22):
    if i < 5:
        year.append(2017)
    elif i < 11:
        year.append(2018)
    elif i < 17:
        year.append(2019)
    else:
        year.append(2020)
ticks = [datetime.strptime(str(year[i]) + str(month[i]), '%Y%m') for i in range(22)]
ax.set_xticks(ticks)
ax.set_xticklabels([])
# 图例
ax.legend(loc='upper right', ncol=3, fontsize=10)

# # 降水和PM10
ax1 = fig.add_subplot(2, 1, 2)
l1 = ax1.bar(np.arange(40), rain_1mon['rainfall'].loc['2017-04-01':'2020-10-01'], width=0.5, linewidth=4, color='grey', alpha=0.6, label='Precipitation')
ax1.set_ylabel('Rainfall(mm)', fontdict=font)
# 纵坐标
ax1.set_ylim((1, 450))
ax1.set_yticks([0, 100, 200, 300, 400])
ax1.set_yticklabels([0, 100, 200, 300, 400], fontdict=font)
# 设置横坐标月份
labels = [(i-8) % 12 for i in range(43)]
for i in range(len(labels)):
    if labels[i] == 0:
        labels[i] = 12
ax1.set_xticks(np.arange(0, 43, 2))
ax1.set_xticklabels(labels[::2], fontdict=font)
# 标记横坐标的年份
ax1.set_title('2017' + ' ' * 13 + '|' + ' ' * 19 + '2018' + ' ' * 20 + '|' + ' ' * 20 + '2019' + ' ' * 19 + '|'+ ' ' * 18  + '2020', x=0.495, y=-0.25, fontdict=font)
# 设置文本标签(b)
ax1.text(-2.15, 405, '(b)', fontdict=font)

#绘制副坐标
ax2 = ax1.twinx()
l2 = ax2.scatter(np.arange(43), pm10_1mon['PM10'].loc['2017-04-01':'2020-10-01'], marker='o', color='none', edgecolors='black', label='PM10')
ax2.set_ylabel(r'$PM10(\mu g·m^{-3})$', fontdict=font)
# 纵坐标
ax2.set_ylim((1, 170))
ax2.set_yticks([0, 50, 100, 150])
ax2.set_yticklabels([0, 50, 100, 150], fontdict=font)
# 横坐标名称
ax2.set_title('Date', x=0.483, y=-0.35, fontdict=font)
# 设置图例
ax2.legend(handles=[l1, l2], loc='upper right', ncol=2, fontsize=10)
# # 调整子图间距,横纵
plt.subplots_adjust(wspace=0.0, hspace=0.1)
plt.savefig('2.2 降水和灰霾与反照率的对比图.svg',  bbox_inches='tight', pad_inches=0.1)

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...