【问题标题】:Second Matplotlib figure doesn't save to file第二个 Matplotlib 图不保存到文件
【发布时间】:2017-05-05 21:35:30
【问题描述】:

我绘制了一个类似于以下内容的图:

它是使用以下代码创建的:

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt

# 1. Plot a figure consisting of 3 separate axes
# ==============================================

plotNames = ['Plot1','Plot2','Plot3']

figure, axisList = plt.subplots(len(plotNames), sharex=True, sharey=True)

tempDF = pd.DataFrame()
tempDF['date'] = pd.date_range('2015-01-01','2015-12-31',freq='D')
tempDF['value'] = np.random.randn(tempDF['date'].size)
tempDF['value2'] = np.random.randn(tempDF['date'].size)

for i in range(len(plotNames)):
    axisList[i].plot_date(tempDF['date'],tempDF['value'],'b-',xdate=True)

# 2. Create a new single axis in the figure. This new axis sits over
# the top of the axes drawn previously. Make all the components of
# the new single axis invisibe except for the x and y labels.

big_ax = figure.add_subplot(111)
big_ax.set_axis_bgcolor('none')
big_ax.set_xlabel('Date',fontweight='bold')
big_ax.set_ylabel('Random normal',fontweight='bold')
big_ax.tick_params(labelcolor='none', top='off', bottom='off', left='off', right='off')
big_ax.spines['right'].set_visible(False)
big_ax.spines['top'].set_visible(False)
big_ax.spines['left'].set_visible(False)
big_ax.spines['bottom'].set_visible(False)

# 3. Plot a separate figure
# =========================
figure2,ax2 = plt.subplots()

ax2.plot_date(tempDF['date'],tempDF['value2'],'-',xdate=True,color='green')
ax2.set_xlabel('Date',fontweight='bold')
ax2.set_ylabel('Random normal',fontweight='bold')

# Save plot
# =========
plt.savefig('tempPlot.png',dpi=300)

基本上,绘制全图的基本原理如下:

  1. 创建第一个图形并使用循环绘制 3 个单独的轴
  2. 在同一图形中绘制单个轴以位于图形顶部 之前画的。标记 x 和 y 轴。使所有其他方面 此轴不可见。
  3. 创建第二个图形并在单个轴上绘制数据。

使用 jupyter-notebook 时,该图的显示方式与我想要的一样,但是保存该图时,该文件仅包含第二个图形。

我的印象是绘图可以有多个图形,并且图形可以有多个轴。但是,我怀疑我对图、子图、图形和轴之间的差异存在根本性的误解。有人可以解释我做错了什么并解释如何将整个图像保存到单个文件中。

【问题讨论】:

  • 我认为当您调用 plt.savefig 时,它会抓取当前图形并绘制它。
  • figure.savefig('figure1.png') 将保存第一个数字,figure2.savefig('figure2.png') 将保存第二个数字。
  • 所以,我想我只需要一个可以保存到单个文件中的图形。是否可以将前 3 个(蓝色)轴分组为图形的单个区域,而将底部(绿色)轴作为第二个不同的区域?

标签: pandas matplotlib


【解决方案1】:

Matplotlib 没有“绘图”。从这个意义上说,

  • 图是数字
  • 子图是坐标轴

在脚本运行期间,您可以拥有任意数量的图形。调用plt.save() 将保存当前活动的数字,即您通过调用plt.gcf() 获得的数字。
您可以通过提供图号num 来保存任何其他图:

plt.figure(num)
plt.savefig("output.png") 

或者通过引用图形对象fig1

fig1.savefig("output.png") 

为了将多个数字保存到一个文件中,可以采用此处详述的方式:Python saving multiple figures into one PDF file。 另一种选择不是创建多个图形,而是使用子图创建一个图形,

fig = plt.figure()
ax = plt.add_subplot(611)
ax2 = plt.add_subplot(612)
ax3 = plt.add_subplot(613)
ax4 = plt.add_subplot(212)

然后使用

将相应的图表绘制到这些轴上
ax.plot(x,y)

或者对于熊猫数据框df

df.plot(x="column1", y="column2", ax=ax)

第二个选项当然可以使用网格上的子图推广到任意轴位置。这在 matplotlib 用户指南Customizing Location of Subplot Using GridSpec中有详细说明 此外,可以使用fig.add_axes([left, bottom, width, height])(其中left, bottom, width, height在图形坐标中,范围从0到1)将轴(可以说是子图)定位在图形中的任何位置。

【讨论】:

  • 谢谢。这个答案有助于提高我的理解。关于 add_subplot() 的 cmets 很有用,但并不像我想要的那样通用。如果我理解正确,对 add_subplot() 的最终调用会产生一个“位于”底部三个(共六个)图的轴。如果底部图的高度等于前三个图的组合高度,则此方法有效。但是,如果底部图需要是前 3 个图中的 2 个的高度,则该方法将分崩离析。不过,这是一个非常有用的提示,我已经升级了答案(但无法将其标记为已接受的答案)。
  • 这里我以问题中给出的例子为例。其他子图排列也是同样可能的。我更新了答案。
猜你喜欢
  • 2018-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 2019-08-08
  • 1970-01-01
  • 2011-11-21
相关资源
最近更新 更多