【问题标题】:How to compile multiple plots into a single plot in Python?如何在 Python 中将多个图编译成一个图?
【发布时间】:2020-10-01 23:36:48
【问题描述】:

我目前正在尝试将多个图组合成一个图(带有子图)。请查看以下代码:

import matplotlib.pyplot as plt

a = list(range(1,10))
b = list(map(lambda x: x**2, a))
c = list(map(lambda x: x**3, a))
d = list(map(lambda x: x+200, a))

plots = []

plt.plot(a, b)
plots.append(plt.gcf())
plt.close()

plt.plot(a, c)
plots.append(plt.gcf())
plt.close()

plt.plot(b, c)
plots.append(plt.gcf())
plt.close()

plt.plot(a, d)
plots.append(plt.gcf())
plt.close()

fig, ax = plt.subplots(len(plots))
for i,plot_obj in enumerate(plots, start=1):
    print(f"{i=}, {plot_obj=}")
    ax[i].set_figure(plot_obj)
    plot_obj.show()


plt.tight_layout()
plt.show()

# plt.savefig('temp.png')

我的限制是 -

  1. 绘图将更早创建 - 我将 figure 对象存储在列表中。
  2. 这些图需要稍后在代码中访问,并且需要创建一个图,每个图都作为子图。

在运行上述代码时,我在尝试设置每个子图的图形时遇到了错误 - RuntimeError: Can not put single artist in more than one figure。思考过程是用保存的figure 对象设置每个子图的图形。有没有办法做到这一点?

谢谢!

【问题讨论】:

  • 为什么不使用子图,见here
  • @ted930511 这没有帮助。该链接告诉您如何绘制多个子图,我正在寻找的内容比这更具体。之前生成图,之后需要通过编译所有图来创建单个图。
  • 我想要这个功能,因为单个图形的绘制成本很高?
  • 问题是不带参数调用 plt.figure() 会创建一个 new 图形,因此您的代码附加到 plots 列表的是那些新图形,而不是那些你想要的。
  • @Arne 是的,你是对的。我现在更新了代码。我可以在遍历绘图时将图形保存在文件中,但我无法使用子绘图作为每个保存的绘图来构建最终绘图。

标签: python matplotlib plot


【解决方案1】:

这可能不是最简洁的编写方式,但我想它可以满足您的需求:

a = list(range(1,10))
b = list(map(lambda x: x**2, a))
c = list(map(lambda x: x**3, a))
d = list(map(lambda x: x+200, a))

plots = []

fig=plt.figure()
plt.plot(a, b)
plots.append(fig)
plt.close()

fig=plt.figure()
plt.plot(a, c)
plots.append(fig)
plt.close()

fig=plt.figure()
ax3= plt.plot(b, c)
plots.append(fig)
plt.close()

fig=plt.figure()
plt.plot(a, d)
plots.append(fig)
plt.close()

fig,axs =plt.subplots(2,2)
axs[0,0].plot(a,b)
axs[0,1].plot(a,c)
axs[1,0].plot(b,c)
axs[1,1].plot(a,d)
plt.tight_layout()

plt.savefig('temp.png')

【讨论】:

  • 谢谢。但这不是我要找的。您的代码将figure 对象保存在plots 列表中,但在最终图形(带有子图)创建过程中没有使用它们。此外,每个子图都是通过再次绘制数据来创建的。基本上,最后几个 LOC 完成了全部工作。我需要先保存绘图对象,然后再在子图中使用它们。问题是,我的项目在构建最终图形时无法访问数据(a、b、c、d),只有figure 对象会在那里。
【解决方案2】:

如果您将各个图保存到文件中,您可以稍后使用matplotlib.image 库中的imshow()imread() 将它们拼凑成一个图:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg

a = list(range(1,10))
b = list(map(lambda x: x**2, a))
c = list(map(lambda x: x**3, a))
d = list(map(lambda x: x+200, a))

def save_plot(x, y, name):
    fig, ax = plt.subplots()
    ax.plot(x, y)
    ax.figure.savefig(name)
    plt.close()
        
save_plot(a, b, 'plot1')
save_plot(a, c, 'plot2')
save_plot(b, c, 'plot3')
save_plot(a, d, 'plot4')

fig, axs = plt.subplots(2, 2)
for i, ax in enumerate(axs.flat):
    ax.set_axis_off()
    filename = 'plot' + str(i+1) + '.png'
    ax.imshow(mpimg.imread(filename))
plt.show()

您可能需要查看imshow() documentation 以减少每个子图周围的空白。

【讨论】:

  • 这不是我想要的,但它是一个很好的解决方法。谢谢@Arne!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-12-25
  • 2020-09-26
相关资源
最近更新 更多