首页 > 解决方案 > 如何正确地将对数比例图与背景图像结合起来?

问题描述

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

标签: pythonmatplotlibimread

解决方案


问题是更改为对数比例轴,图像也会变形。因此,图像需要线性比例。

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

主轴zorder位于辅助轴的前面。所以新的曲线是最重要的。为了使图像可见,主轴的 facecolor 需要是透明的(颜色字符串 'none' 而不是默认的 'white')。

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:另一种方法可能是在同一轴上绘制所有内容,但手动将曲线坐标转换为对数空间。然后,轴对于图像和曲线都是线性的。正如本文所探讨的,轴的视觉方面可以适应模拟对数轴。


推荐阅读