如何正确地将对数比例图与背景图像结合起来?

How to properly combine a log scale plot with a background image?

我为一条曲线生成了数据,存储在一个列表中。然后我从这些数据中随机抽取了 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,

问题是改成对数刻度轴,图像也会变形。所以,图像需要一个线性比例尺。

一种方法是在辅助 x 轴和 y 轴上绘制图像,并使用线性比例。并以双对数刻度在原始轴上绘制曲线。

主轴得到一个 zorder 在次轴的前面。因此,新曲线高于一切。要使图像可见,主轴的面色需要透明(颜色字符串 'none' 而不是默认值 'white')。

要隐藏辅助轴,还需要隐藏中间 twinx()。 (见this post下的备注。)

为了使宽高比正确,只有 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:另一种方法是在同一轴上绘制所有内容,但手动将曲线坐标转换为 log space。然后,轴对于图像和曲线都是线性的。正如 .

中探讨的那样,轴的视觉方面可以适应模拟对数轴