Измените диапазон осей на широту и долготу с помощью matplotlib в python

#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 .