Matplotlib调用imshow绘图时xticks/yticks首个刻度标签丢失问题
问题原因
set_xticklabels()、set_yticklabels()两个方法仅能为坐标轴当前已有的刻度位置分配文本标签,不会主动调整刻度的位置,也不会自动匹配你传入的标签数组的长度。
调用imshow()加载图片后,Matplotlib会根据图片的像素尺寸默认生成刻度,默认的边缘刻度有可能被画布边距规则隐藏,或是生成的刻度数量和你传入的标签数量不匹配,最终导致第一个标签被跳过,直接从第二个标签开始匹配现有刻度。
解决方法
有两种可行方案,推荐使用第一种,更适配地理底图的使用场景:
方案1:绑定图片坐标范围(推荐)
通过imshow()的extent参数直接将图片像素坐标映射到你的经纬度范围,再显式指定刻度位置与标签一一对应,后续叠加其他地理数据也不需要额外做坐标转换。
修改后的完整代码如下:
import numpy as np import matplotlib.pyplot as plt from PIL import Image point=(1.28358, 103.86921, 1.11504, 104.16138) #BATAM3 im = Image.open('BATAM3.png', 'r') x_tick = list(map(lambda x: round(x, 7), np.linspace(point[1], point[3], endpoint=True, num=9))) y_tick = list(map(lambda x: round(x, 7), np.linspace(point[2], point[0], endpoint=True, num=6))) y_tick = sorted(y_tick, reverse=True) fig, ax = plt.subplots(figsize=(15, 15)) # extent参数格式为(最小经度, 最大经度, 最小纬度, 最大纬度),origin默认upper匹配y轴从上到下纬度递减的规则 ax.imshow(im, extent=(point[1], point[3], point[2], point[0])) ax.set_xlabel('Longitude') ax.set_ylabel('Latitude') # 先显式指定刻度位置,和标签数组长度完全匹配 ax.set_xticks(x_tick) ax.set_yticks(y_tick) # 再为刻度分配标签 ax.set_xticklabels(x_tick) ax.set_yticklabels(y_tick) ax.grid() plt.show()
方案2:仅匹配像素刻度位置
如果不需要使用真实经纬度坐标,仅需要匹配标签,也可以直接将刻度位置设置为图片像素的均匀分布点:
在调用set_xticklabels/set_yticklabels前添加如下代码即可:
# x轴均匀分布9个刻度,对应9个标签 ax.set_xticks(np.linspace(0, im.width, 9)) # y轴均匀分布6个刻度,对应6个标签 ax.set_yticks(np.linspace(0, im.height, 6))
内容的提问来源于stack exchange,提问作者Mochamad Arief Noviyandi
相关产品推荐
相关产品推荐

