python - 使用 matplotlib 在图像文件上绘制半透明轮廓图

标签 python matplotlib plot contour

我想在 matplotlib/pyplot 中的图像文件上绘制透明等高线图。

这是我到目前为止得到的...

我有一个 600x600 像素的正方形图像文件 test.png 如下所示:

enter image description here

我想使用 matplotlib 和 pyplot 在该图像上绘制等高线图(图像文件位于“下方”,并覆盖等高线图的半透明版本)。作为奖励,图像将自动缩放以适应当前绘图边界。我的示例绘图脚本如下:

from matplotlib import pyplot
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
from matplotlib.colors import BoundaryNorm
from matplotlib.ticker import MaxNLocator
from pylab import *
import numpy as np
import random

# ----------------------------- #

dx, dy = 500.0, 500.0
y, x = np.mgrid[slice(-2500.0, 2500.0 + dy, dy),slice(-2500.0, 2500.0 + dx, dx)]

z = []
for i in x:
    z.append([])
    for j in y:
        z[-1].append(random.uniform(80.0,100.0))

# ----------------------------- #

plot_aspect = 1.2
plot_height = 10.0
plot_width = int(plot_height*plot_aspect)

# ----------------------------- #

pyplot.figure(figsize=(plot_width, plot_height), dpi=100)
pyplot.subplots_adjust(left=0.10, right=1.00, top=0.90, bottom=0.06, hspace=0.30)
subplot1 = pyplot.subplot(111)

# ----------------------------- #

cbar_max = 100.0
cbar_min = 80.0
cbar_step = 1.0
cbar_num_colors = 200
cbar_num_format = "%d"

# ----------

levels = MaxNLocator(nbins=cbar_num_colors).tick_values(cbar_min, cbar_max)
cmap = pyplot.get_cmap('jet')
norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True)
pp = pyplot.contourf(x,y,z,levels=levels,cmap=cmap)
cbar = pyplot.colorbar(pp, orientation='vertical', ticks=np.arange(cbar_min, cbar_max+cbar_step, cbar_step), format=cbar_num_format)
cbar.ax.set_ylabel('Color Scale [unit]', fontsize = 16, weight="bold")

# ----------

CS = pyplot.contour(x,y,z, alpha=0.5)

# ----------

majorLocator1   = MultipleLocator(500)
majorFormatter1 = FormatStrFormatter('%d')
minorLocator1   = MultipleLocator(250)

subplot1.xaxis.set_major_locator(majorLocator1)
subplot1.xaxis.set_major_formatter(majorFormatter1)
subplot1.xaxis.set_minor_locator(minorLocator1)

pyplot.xticks(fontsize = 16)
pyplot.xlim(-2500.0,2500.0)

# ----------

majorLocator2   = MultipleLocator(500)
majorFormatter2 = FormatStrFormatter('%d')
minorLocator2   = MultipleLocator(250)

subplot1.yaxis.set_major_locator(majorLocator2)
subplot1.yaxis.set_major_formatter(majorFormatter2)
subplot1.yaxis.set_minor_locator(minorLocator2)

pyplot.yticks(fontsize = 16)
pyplot.ylim(-2500.0,2500.0)

# ----------

subplot1.xaxis.grid()
subplot1.yaxis.grid()

# ----------

subplot1.axes.set_aspect('equal')

# ----------

pyplot.suptitle('Main Title', fontsize = 24, weight="bold")

# ----------

pyplot.xlabel('X [m]', fontsize=16, weight="bold")
pyplot.ylabel('Y [m]', fontsize=16, weight="bold")

# ----------

implot = subplot1.imshow( pyplot.imread('test.png') , interpolation='nearest', alpha=0.5)

# ----------
pyplot.show()
#pyplot.savefig("tmp.png", dpi=100)
pyplot.close()

...但我没有得到我想要的结果...相反,我只看到等高线图部分。像这样的东西:

enter image description here

我应该在我的代码中做什么才能得到我想要的?

最佳答案

您基本上需要做两件事,设置您想要的图像在背景中的范围。如果不这样做,则假定坐标为像素坐标,在本例中,x 和 y 的坐标均为 0 到 600。因此,将 imshow 命令调整为:

implot = subplot1.imshow(pyplot.imread(r'test.png'), interpolation='nearest', 
                         alpha=0.5, extent=[-2500.0,2500.0,-2500.0,2500.0])

如果你想自动拉伸(stretch)图像到绘图的限制,你可以抓取范围:

extent = subplot1.get_xlim()+ subplot1.get_ylim()

并将其作为 extent=extent 传递给 imshow

由于它是背景图像,将 alpha 设置为 0.5 会使它变得非常微弱,我将其设置为 1.0。

其次,您设置了轮廓线的 alpha,但您可能还(或尤其是)想要设置填充轮廓的 alpha。当您使用带填充轮廓的 alpha 时,启用抗锯齿可减少伪影。因此,将您的 contourf 命令更改为:

pp = pyplot.contourf(x,y,z,levels=levels,cmap=cmap, alpha=.5, antialiased=True)

并且由于您已经自己创建了子图对象,我建议还使用它来进行绘图,而不是在当前事件轴上运行的 pyplot 界面。

所以:

subplot1.contourf()
etc

代替:

pyplot.contourf()

通过上面提到的两个更改,我的结果如下:

enter image description here

关于python - 使用 matplotlib 在图像文件上绘制半透明轮廓图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32652428/

相关文章:

python - 将str转换为numpy.ndarray

python - Seaborn Jointplot 为每个类添加颜色

python - MatPlotLib绕固定轴旋转3D图

python - pandas plotting.py 代码中缺少全局转换对象?

python - 测量函数的执行时间

python - pd.pivot_table 如何/在哪里存储或引用其索引和列变量的名称?

python - pyspark 在没有 pandas 的情况下将一列拆分为多列

python - Pandas/Matplotlib 在一列上进行注释并在另一列上添加标签

r - 根据 ggplot 中其他列中的值在 ggplot 中包含垂直线

python - 使用 pandas 在 matplotlib 中绘图