将图形写入Google Cloud Storage而不是本地驱动器

时间:2019-01-16 19:10:16

标签: python-3.x matplotlib google-cloud-platform google-cloud-storage

我想将用matplotlib制作的图形上传到GCS。

当前代码:

from tensorflow.gfile import MakeDirs, Open
import numpy as np
import matplotlib.pyplot as plt
import datetime

_LOGDIR = "{date:%Y%m%d-%H%M%S}".format(date=datetime.datetime.now())

_PATH_LOGDIR = 'gs://{0}/logs/{1}'.format('skin_cancer_mnist', _LOGDIR)
MakeDirs(_PATH_LOGDIR))


def saving_figure(path_logdir):
    data = np.arange(0, 21, 2)
    fig = plt.figure(figsize=(20, 10))
    plt.plot(data)
    fig.savefig("{0}/accuracy_loss_graph.png".format(path_logdir))
    plt.close()

saving_figure(_PATH_LOGDIR)

“ / Library / Frameworks / Python.framework / Versions / 3.5 / lib / python3.5 / site-packages / matplotlib / backends / backend_agg.py”,行512,在print_png中     filename_or_obj =打开(filename_or_obj,'wb')

FileNotFoundError:[错误2]没有此类文件或目录:'gs://skin_cancer_mnist/logs/20190116-195604/accuracy_loss_graph.png'

(目录存在,我检查过了)

我可以更改matplotlib的源代码以使用tf.Gfile.Open的Open方法,但是应该有一个更好的选择...

2 个答案:

答案 0 :(得分:2)

您无法使用python open功能(matplotlib.pyplot.savefig在幕后使用的功能)直接将文件上传到Google Cloud Storage。 相反,您应该使用Cloud Storage Client Library for Python。检查此documentation,以了解有关如何使用此库的详细信息。这将允许您处理文件并将其上传/下载到GCS等。

您必须先导入该库才能使用它,可以通过运行pip install google-cloud-storage进行安装并将其导入为from google.cloud import storage

同样,由于plt.figure是对象,而不是您要上传的实际.png图像,因此您也不能直接将其上传到Google Cloud Storage。

但是您可以执行以下任一操作:

选项1 :在本地保存图片,然后将其上传到Google Cloud Storage:

使用您的代码:

from google.cloud import storage

def saving_figure(path_logdir):
    data = np.arange(0, 21, 2)
    fig = plt.figure(figsize=(20, 10))
    plt.plot(data)
    fig.savefig("your_local_path/accuracy_loss_graph.png".format(path_logdir))
    plt.close()


    # init GCS client and upload file
    client = storage.Client()
    bucket = client.get_bucket('skin_cancer_mnist')
    blob = bucket.blob('logs/20190116-195604/accuracy_loss_graph.png')  # This defines the path where the file will be stored in the bucket
    your_file_contents = blob.upload_from_filename(filename="your_local_path/accuracy_loss_graph.png")

选项2 :将图片中的图片结果保存到变量中,然后将其作为字符串(字节)上传到GCS:

我找到了以下StackOverflow答案,该答案似乎将图形图像保存到.png字节字符串中,但是我自己还没有尝试过。

再次根据您的代码:

from google.cloud import storage
import io
import urllib, base64

def saving_figure(path_logdir):
    data = np.arange(0, 21, 2)
    fig = plt.figure(figsize=(20, 10))
    plt.plot(data)
    fig_to_upload = plt.gcf()

    # Save figure image to a bytes buffer
    buf = io.BytesIO()
    fig_to_upload.savefig(buf, format='png')
    buf.seek(0)
    image_as_a_string = base64.b64encode(buf.read())

    # init GCS client and upload buffer contents
    client = storage.Client()
    bucket = client.get_bucket('skin_cancer_mnist')
    blob = bucket.blob('logs/20190116-195604/accuracy_loss_graph.png')  # This defines the path where the file will be stored in the bucket
    your_file_contents = blob.upload_from_string(image_as_a_string, content_type='image/png')

编辑:这两个选项均假定您正在运行脚本的环境,已安装Cloud SDK以及已激活的Google Cloud身份验证帐户(如果没有,则可以请查看this documentation,其中说明了操作方法。

答案 1 :(得分:0)

Joans 2nd Option 对我不起作用,我找到了一个对我有用的解决方案:

from google.cloud import storage
import io

def saving_figure(path_logdir):
    data = np.arange(0, 21, 2)
    fig = plt.figure(figsize=(20, 10))
    plt.plot(data)
    fig_to_upload = plt.gcf()

    # Save figure image to a bytes buffer
    buf = io.BytesIO()
    fig_to_upload.savefig(buf, format='png')

    # init GCS client and upload buffer contents
    client = storage.Client()
    bucket = client.get_bucket('skin_cancer_mnist')
    blob = bucket.blob('logs/20190116-195604/accuracy_loss_graph.png')  
    blob.upload_from_file(buf, content_type='image/png', rewind=True)