Как правильно совместить график логарифмической шкалы с фоновым изображением?

Я произвел данные для кривой, сохраненные в списке. Затем я взял 1000 случайных выборок из этих данных. По оси Y показаны мои данные, а по оси X — вывод формулы. До сих пор все в порядке. Проблема начинается, когда я хочу нанести свои данные на существующее изображение.

Рисунок

Как видите, мои оси x и y имеют логарифмическую шкалу и меньше 1. Я искал ответы и обнаружил, что могу использовать FuncFormatter. Однако у меня это не работает, так как мне нужно отображать данные в логарифмическом масштабе. Когда я использую просто plt.xscale('log'), рисунок выглядит так:

Выходная цифра с логарифмической шкалой

изображение

Выходная цифра без логарифмической шкалы

изображение

import matplotlib.pyplot as plt
import numpy as np

#Producing some data and put them in a list named listGercek 

xekseni2 = []
data = random.sample(listGercek, 1000)

for teta in data:
    olasılık = listGercek.index(teta)/100000
    xekseni2.append(olasılık)

im = plt.imread('figure.png')
xmin, xmax, ymin, ymax = (0.001, 1, 0.01, 1)
aspect = im.shape[0] / im.shape[1] * (xmax-xmin)/(ymax-ymin)
plt.imshow(im, zorder=0, extent=[1e-3, 1e0, 1e-2, 1e0], aspect=aspect)
plt.yscale('log')
plt.xscale('log')
plt.xlabel('P')
plt.ylabel(r'$\tau_{c}^{*}$')
plt.plot(xekseni2, data, "ro", marker="o", markersize=1, label="Present Work")
plt.axis([xmin, xmax, ymin, ymax])
plt.legend()
plt.show()

Некоторые данные по запросу:

y:0.09141346037829952, 0.06969760102294438, 0.0473781028644485, 0.059295628198887916, 0.0571418702849134, 0.04050307759274645, 0.08088991113201109, 0.03746878506083184, 0.13583224333004337, 0.03269066677698429, 0.06918929672995293, 0.06040315211901601, 0.05772815718352134, 0.07361582566248871, 0.06212973486945907, 0.03283216378016191, 0.14407484921136313, 0.02266323793619761, 0.04439409523587426, 0.055067724315696655,

x:0.81136, 0.67958, 0.43465, 0.58106, 0.55695, 0.33327, 0.75665, 0.2849, 0.93146, 0.20716, 0.6752, 0.59276, 0.56391, 0.70997, 0.6097, 0.20941, 0.94315, 0.06609, 0.39222, 0.53361,


person omerS    schedule 18.03.2020    source источник
comment
Можете ли вы добавить некоторые данные? Например, 20 x, y позиций вашей кривой?   -  person JohanC    schedule 19.03.2020
comment
конечно могу добавить. @johanC   -  person omerS    schedule 19.03.2020


Ответы (1)


Проблема в том, что при переходе на оси логарифмического масштаба изображение также деформируется. Итак, изображение нуждается в линейном масштабе.

Один из подходов состоит в том, чтобы нарисовать изображение на вторичных осях x и y с линейным масштабом. И нарисовать кривую на исходных осях с двойным логарифмическим масштабом.

Первичные оси получают zorder перед вторичными осями. Таким образом, новая кривая идет поверх всего. Чтобы сделать изображение видимым, цвет лицевой стороны основных осей должен быть прозрачным (цветовая строка «нет» вместо «белого» по умолчанию).

Чтобы скрыть вторичную ось, также необходимо скрыть промежуточную twinx(). (См. примечания под этим сообщением.)

Чтобы получить правильное соотношение сторон, кажется, что работает только aspect='auto', устанавливая одинаковые пределы как для основной, так и для вторичной осей.

import matplotlib.pyplot as plt
import numpy as np

xekseni2 = [0.81136, 0.67958, 0.43465, 0.58106, 0.55695, 0.33327, 0.75665, 0.2849, 0.93146, 0.20716, 0.6752, 0.59276,
            0.56391, 0.70997, 0.6097, 0.20941, 0.94315, 0.06609, 0.39222, 0.53361]
data = [0.09141346037829952, 0.06969760102294438, 0.0473781028644485, 0.059295628198887916, 0.0571418702849134,
        0.04050307759274645, 0.08088991113201109, 0.03746878506083184, 0.13583224333004337, 0.03269066677698429,
        0.06918929672995293, 0.06040315211901601, 0.05772815718352134, 0.07361582566248871, 0.06212973486945907,
        0.03283216378016191, 0.14407484921136313, 0.02266323793619761, 0.04439409523587426, 0.055067724315696655]

xmin, xmax, ymin, ymax = (0.001, 1, 0.01, 1)

ax = plt.gca()
ax.plot(xekseni2, data, "ro", marker="o", markersize=1, label="Present Work")
ax.set_yscale('log')
ax.set_xscale('log')
ax.set_xlabel('P')
ax.set_ylabel(r'$\tau_{c}^{*}$')
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
ax.legend(loc='lower right')
ax.set_zorder(2)
ax.set_facecolor('none')

ax_tw_x = ax.twinx()
ax_tw_x.axis('off')
ax2 = ax_tw_x.twiny()

im = plt.imread('figure.png')
ax2.imshow(im, extent=[xmin, xmax, ymin, ymax], aspect='auto')
ax2.axis('off')
plt.show()

результат

PS: Другой подход может заключаться в том, чтобы рисовать все на одних и тех же осях, но вручную преобразовывать координаты кривой в пространство журнала. В этом случае оси являются линейными как для изображения, так и для кривой. Визуальный аспект осей можно адаптировать для имитации логарифмических осей, как описано в этом сообщении.

person JohanC    schedule 18.03.2020