如何创建第二个(新的)图表,然后在旧图表上绘制?

208
我想绘制数据,然后创建一个新的图形并绘制数据2,最后回到原始图形并绘制数据3,就像这样:
import numpy as np
import matplotlib as plt

x = arange(5)
y = np.exp(5)
plt.figure()
plt.plot(x, y)

z = np.sin(x)
plt.figure()
plt.plot(x, z)

w = np.cos(x)
plt.figure("""first figure""") # Here's the part I need
plt.plot(x, w)

FYI 如何告诉matplotlib我已经完成了一个图表?做了类似的事情,但不完全一样!它不允许我访问原始图表。
6个回答

191
如果你经常这样做,那么调查一下面向对象的 matplotlib 接口可能是值得的。在你的情况下:
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(5)
y = np.exp(x)
fig1, ax1 = plt.subplots()
ax1.plot(x, y)
ax1.set_title("Axis 1 title")
ax1.set_xlabel("X-label for axis 1")

z = np.sin(x)
fig2, (ax2, ax3) = plt.subplots(nrows=2, ncols=1) # two axes on figure
ax2.plot(x, z)
ax3.plot(x, -z)

w = np.cos(x)
ax1.plot(x, w) # can continue plotting on the first axis

虽然有点罗嗦,但更加清晰易懂,并且在每个图形都有多个子图的情况下更容易跟踪。


4
我更喜欢面向对象的方法,因为当我预计会有很多图形时,使用名称而不是数字来跟踪它们会更容易。谢谢! - Peter D
1
但是,如何使用这种方法更改标签和轴限制呢?如果我使用 ax1.ylabel,它会显示未找到。同样的情况也出现在 fig1.ylabel 上... - George Datseris
4
语法有点不同。它应该是 ax1.set_xlabel("你的 x 标签")ax1.set_ylabel("你的 y 标签")ax1.set_title("你的标题") - simonb
1
你为什么使用111? - Yash Sodha
3
@yashSodha - 这是一个Matlab风格的子图数量规范(行,列,索引)。但现在使用plt.subplots(nrows, ncols)更容易。已更新示例。 - simonb
我给你点赞了,因为你的答案对我有帮助,谢谢!但是你能否请添加一些图片到你的回答中,或者使用不同参数提供更多示例?我的意思是,我不得不查阅文档来寻找最佳解决方案。如果能够添加具有不同效果的图像,将会非常有帮助。 - KareemJ

182

当您调用 figure 时,简单地对图进行编号。

x = arange(5)
y = np.exp(5)
plt.figure(0)
plt.plot(x, y)

z = np.sin(x)
plt.figure(1)
plt.plot(x, z)

w = np.cos(x)
plt.figure(0) # Here's the part I need
plt.plot(x, w)

编辑:请注意,您可以随意给图形编号(在此处从0开始),但如果在创建新图形时根本不提供编号,自动编号将从1开始(根据文档,“Matlab风格”)。


4
在Matplotlib的交互模式下,这似乎有效,而figure()...add_subplot()方法则不行。谢谢! - chbrown
2
@SebMa 请在理解代码之前不要更改它。这个答案特别是关于将数字传递给 figure,而你却删除了它。你更改的其他内容都是从原始帖子中复制的,而不是我的答案中的错误。 - agf
@agf 你好,我把 plt.figure(1) 中的 1 删除了,因为我认为数字会自动递增,所以不必要。抱歉。 - SebMa
但是只有figure(0)获得了标题和图例 - Nathan B

25

然而,编号从1开始,因此:

x = arange(5)
y = np.exp(5)
plt.figure(1)
plt.plot(x, y)

z = np.sin(x)
plt.figure(2)
plt.plot(x, z)

w = np.cos(x)
plt.figure(1) # Here's the part I need, but numbering starts at 1!
plt.plot(x, w)

另外,如果您在图中有多个轴,比如子图,请使用axes(h)命令,其中h是所需轴对象的句柄,以便将焦点放在该轴上。

(我还没有评论权限,很抱歉只能用回答来回复!)


12
0不起作用,自动编号从1开始,如果您完全不指定编号。 - agf

5

接受的答案建议使用面向对象接口 (matplotlib),但是答案本身结合了一些MATLAB风格的接口matplotib.pyplot)。

如果你喜欢这种方式,完全可以使用OOP方法

import numpy as np
import matplotlib

x = np.arange(5)
y = np.exp(x)
first_figure      = matplotlib.figure.Figure()
first_figure_axis = first_figure.add_subplot()
first_figure_axis.plot(x, y)

z = np.sin(x)
second_figure      = matplotlib.figure.Figure()
second_figure_axis = second_figure.add_subplot()
second_figure_axis.plot(x, z)

w = np.cos(x)
first_figure_axis.plot(x, w)

display(first_figure) # Jupyter
display(second_figure)

这使用户可以手动控制图形,避免了与pyplot内部状态仅支持单个图形有关的问题。


3

将每次迭代的绘图分别绘制在单独的框架中的简单方法如下:

import matplotlib.pyplot as plt  
for grp in list_groups:
        plt.figure()
        plt.plot(grp)
        plt.show()

然后Python将绘制不同的帧。

似乎正是OP所要求的,也是在使用原始界面时所需的。 - mins

1

在一些探索后,我找到了一种方法,即创建一个函数,该函数获取data_plot矩阵、文件名和顺序作为参数,以从有序图中的给定数据创建箱线图(不同的顺序=不同的图形),并将其保存在给定的文件名下。

def plotFigure(data_plot,file_name,order):
    fig = plt.figure(order, figsize=(9, 6))
    ax = fig.add_subplot(111)
    bp = ax.boxplot(data_plot)
    fig.savefig(file_name, bbox_inches='tight')
    plt.close()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接