在Python中,有没有一种方法可以在for循环中保存多个图形而不会覆盖之前的图形?

3

我有一个聚合了不同国家交易统计数据的数据框列表。我能够通过循环遍历这个数据框列表生成相应的图表。现在,我想要将这些图表保存到本地而不覆盖之前保存的文件,也就是说,为每个图表保存其相应的标题名称。为此,我尝试了以下方法:

我有一个数据框列表,它们具有如下名称:

[dfList[i].name for i in range(len(dfList))]

['AR  fresh-Beef-E',
 'AUC  fresh-Beef-E',
 'BR  fresh-Beef-E',
 'CA  fresh-Beef-E',
 'CL  fresh-Beef-E',
 'CN  fresh-Beef-E',
 'E28  fresh-Beef-E',
 'EG  fresh-Beef-E',
 'IN  fresh-Beef-E',
 'JP  fresh-Beef-E',
 'KR  fresh-Beef-E',
 'MX  fresh-Beef-E',
 'NZ  fresh-Beef-E',
 'PY  fresh-Beef-E',
 'US  fresh-Beef-E',
 'UY  fresh-Beef-E',
 'ZA  fresh-Beef-E']

当前尝试:

打算将图形和其标题作为文件名本地保存:

import os
import pandas as pd
import matplotlib.pyplot as plt

outpath = r'C:/Users/plots'

if os.path.exists(outpath):
    shutil.rmtree(outpath)
_ = os.mkdir(outpath)

for i in range(len(dfList)) :
    plt.figure()
    my_plotter(dfList[i],title=dfList[i].name)
    plt.savefig(path.join(outpath,"dataname_{0}.png".format(i)))
    plt.close()

新更新

这是我的绘图函数的样子:

def my_plotter(df, plot_type='something', ylab_nm='something', title=None):
    fig, ax1 = plt.subplots(figsize=figsize)
    if plot_type=='something':
        _ = df.plot(kind='line', ax=ax1, marker='o', ls='-', linewidth=2, color=colors)
    else:
        df.loc[:, 'Total'] = df.sum(axis=1)
        _ = df.div(df.Total, axis=0).iloc[:, :-1].plot(kind='line', ax=ax1, marker='o', ls='--', linewidth=4, color=colors)
        df.drop('Total', axis=1, inplace=True)
        ax1.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1, decimals=0))
        ax1.xaxis.set_major_locator(mdates.MonthLocator(bymonthday=1, interval=3))

    ax1.set(title=title)
    plt.title(title)
    ax1.xaxis.label.set_visible(False)
    plt.style.use('ggplot')
    plt.xticks(rotation=90)
    plt.show()

但上述尝试并没有将图表保存到本地目录。我查看了 SO 并尝试了一些建议,但是我仍然没有得到所有应该以其情节标题命名并保存到本地文件夹的情节。在我的尝试中,没有一个情节被保存到本地目录。
有人能指出如何使这项工作吗?任何想法? 目标 我打算通过将其标题作为文件名来保存每个图表,并将其保存到本地目录。有什么想法吗?谢谢。
1个回答

3

这不是一个完整的最小工作示例(MWE),但我认为以下修复方法应该会对你有所帮助。

import matplotlib.pyplot as plt
import pandas as pd
import os

# Only need to set the style once (not in loop)
plt.style.use('ggplot')

outpath = r'C:/Users/plots'

def my_plotter(df, plot_type='something', ylab_nm='something', title=None):
    fig, ax1 = plt.subplots(1, 1)
    if plot_type=='something':
        # Plots on ax1, so don't save output as another ax instance
        df.plot(kind='line', ax=ax1, marker='o', ls='-', linewidth=2)
    else:
        df.loc[:, 'Total'] = df.sum(axis=1)
        # Plots on ax1, so don't save output as another ax instance
        df.div(df.Total, axis=0).iloc[:, :-1].plot(kind='line', ax=ax1, marker='o', ls='--', linewidth=4, color=colors)
        df.drop('Total', axis=1, inplace=True)
        ax1.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1, decimals=0))
        ax1.xaxis.set_major_locator(mdates.MonthLocator(bymonthday=1, interval=3))

    ax1.set(title=title)
    ax1.set_title(title, size=24, verticalalignment='bottom') 
    ax1.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
    ax1.xaxis.label.set_visible(False)

    plt.xticks(rotation=90)
    plt.show()
    return fig, ax1

if os.path.exists(outpath):
    shutil.rmtree(outpath)
_ = os.mkdir(outpath)

for i in range(len(dfList)):
    fig, ax1 = my_plotter(dfList[i], title=dfList[i].name)
    fig.savefig(path.join(outpath,"dataname_{}.png".format(dfList[i].name)))
    plt.close()

1
它们只是空的数字和轴吗?my_plotter做了什么? - jwalton
是的,它是一个空图。my_plotter 用于制作时间序列数据的折线图。 - beyond_inifinity
plt.figure() 创建一个空图形。然后您尝试使用 my_plotter 绘制它,但我猜在那里出了些问题(您绘制的图形没有返回,也许是这个原因)。然后您只需保存空图形。 - jwalton
如果你能分享my_plotter,我认为我们可以解决这个问题。 - jwalton
我刚刚发布了我的绘图函数,有什么想法为什么我得到了空图?谢谢。 - beyond_inifinity
显示剩余4条评论

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