#python #matplotlib #axis #latitude-longitude
#python #matplotlib #ось #широта-долгота
Вопрос:
Как я могу использовать оси yaxis и xaxis, которые я хочу, и которые не коррелируют с данными на графике? Например, я хочу отобразить карту мира в виде изображения, используя приведенный ниже код:
import matplotlib.pyplot as plt
fig = plt.figure()
plt.imshow(world_map)
В результате я получил xaxis: 0…размер_изображения_x слева направо и yaxis: 0…размер_изображения_y сверху вниз.
Что мне нужно сделать, чтобы изменить диапазон осей на форматы широты и долготы? Таким образом, ось рисунка должна содержать градусы (от 90 до -90) в обоих полях (x и y) независимо от того, какие ее реальные данные нанесены на рисунок.
Настройка
pylab.ylim([90,-90])
изображение сдвинется к низу на 90 пикселей и уменьшит размер y изображения до масштаба image_size_y /90. Таким образом, это не сработает, потому что xlim / ylim работает с данными, изображенными на рисунке.
Ответ №1:
Короче говоря: используйте extent
ключевое слово with imshow
.
В коде:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subaxis(111)
ax.imshow(world_map, extent=[-180,180,-90,90], aspect='auto')
Если ваша карта перевернута, добавьте аргумент ключевого слова origin='lower'
к imshow
. Это aspect='auto'
необходимо для того, чтобы сделать карту масштабируемой в обоих измерениях независимо. (Остальные дополнительные строки с add_subaxis
предназначены только для того, чтобы сделать код более объектно-ориентированным, настоящая проблема заключается в аргументах ключевого слова.)
Если imshow
не указаны размеры изображения, он считает, что вы захотите, чтобы каждый пиксель был центрирован по позициям (0,0), (0,1), …, ( Nx-1, Ny-1), и тогда экстенты изображения будут начинаться с (-.5, — .5).
Комментарии:
1. Это работает хорошо. Но дело в том, что я использую проекционную карту mercator , где каждые 20 градусов широты (измерение y) имеют разный размер в пикселях. Поэтому я думаю, что лучшим способом будет использовать что-то вроде того, что Томми сказал ниже.
Ответ №2:
Предполагая (на основе вашего сообщения), что изображение в порядке, но метки осей отключены, попробуйте поиграть с этим, что позволит вручную реализовать метки осей:
plt.figure(1)
ax = plt.subplot(111)
#... do your stuff
#need to figure out your image size divided by the number of labels you want
#FOR EXample, if image size was 180, and you wanted every second coordinate labeled:
ax.set_xticks([i for i in range(0,180,2)]) #python3 code to create 90 tick marks
ax.set_xticklabels([-i for i in range(-90,90,2)]) #python3 code to create 90 labels
#DO SAME FOR Y
Трюк, который я использую, заключается в том, чтобы выяснить, сколько меток вы хотите (здесь 90: 180/2), равномерно добавить метки в диапазоне (0, imagesize), затем вручную выполнить метки. Вот общая формула:
ax.set_xticks([i for i in range(0,IMAGE_SIZE,_EVERY_XTH_COORD_LABELED)]) #python3 code to create 90 tick marks
ax.set_xticklabels([-i for i in range(-90,90,EVERY_XTH_COORD_LABELED)]) #python3 code to create 90 labels
Комментарии:
1.
set_xticklabels
почти всегда это плохая идея. Это отделяет ваши метки от ваших данных. Лучше использоватьFuncFormatter
.