Нелинейные оси для imshow в matplotlib
Я создаю 2D-массивы на осях с лог-интервалом (например, координаты x-пикселя генерируются с использованием logspace(log10(0.95), log10(2.08), n)
.
Я хочу отобразить изображение, используя простой старый imshow, в своем собственном разрешении и масштабировании (мне не нужно растянуть его; сами данные уже log scaled), но я хочу добавить тики, метки, строки, которые находятся в правильном месте на осях журнала. Как это сделать?
В идеале я мог бы просто использовать командную строку axvline(1.5)
, и строка была бы в правильном месте (58% слева), но если единственный способ - перевести вручную между координатами лог-шкалы и координатами изображения, это тоже нормально.
Для линейных осей использование extents=
в вызове imshow делает то, что я хочу, но я не вижу способа сделать то же самое с осью журнала.
Пример:
from matplotlib.colors import LogNorm
x = logspace(log10(10), log10(1000), 5)
imshow(vstack((x,x)), extent=[10, 1000, 0, 100], cmap='gray', norm=LogNorm(), interpolation='nearest')
axvline(100, color='red')
Этот пример не работает, потому что extent = применяется только к линейным масштабам, поэтому, когда вы выполняете axvline на 100, он не отображается в центре. Я хотел бы, чтобы ось x показывала 10, 100, 1000 и axvline(100)
, чтобы поместить линию в центр в 100 точках, тогда как пиксели оставались на равном расстоянии.
Ответы
Ответ 1
Собственно, он работает нормально. Я смущен.
Раньше я получал ошибки в отношении "Изображения не поддерживаются на нелинейных осях", поэтому я задал этот вопрос. Но теперь, когда я пытаюсь, он работает:
import matplotlib.pyplot as plt
import numpy as np
x = np.logspace(1, 3, 5)
y = np.linspace(0, 2, 3)
z = np.linspace(0, 1, 4)
Z = np.vstack((z, z))
plt.imshow(Z, extent=[10, 1000, 0, 1], cmap='gray')
plt.xscale('log')
plt.axvline(100, color='red')
plt.show()
Это лучше, чем pcolor()
и pcolormesh()
, потому что
- он не безумно медленный и
- легко интерполируется без ложных артефактов, когда изображение не отображается на собственном разрешении.
Ответ 2
На мой взгляд, лучше использовать pcolor
и регулярные (неконвертированные) значения x и y. pcolor
дает вам большую гибкость, а регулярные оси x и y менее запутывают.
import pylab as plt
import numpy as np
from matplotlib.colors import LogNorm
from matplotlib.ticker import LogFormatterMathtext
x=np.logspace(1, 3, 6)
y=np.logspace(0, 2,3)
X,Y=np.meshgrid(x,y)
z = np.logspace(np.log10(10), np.log10(1000), 5)
Z=np.vstack((z,z))
im = plt.pcolor(X,Y,Z, cmap='gray', norm=LogNorm())
plt.axvline(100, color='red')
plt.xscale('log')
plt.yscale('log')
plt.colorbar(im, orientation='horizontal',format=LogFormatterMathtext())
plt.show()
![enter image description here]()
Поскольку pcolor
работает медленно, более быстрым решением является использование pcolormesh
.
im = plt.pcolormesh(X,Y,Z, cmap='gray', norm=LogNorm())