Python 3.x 将图形写入Google云存储而不是本地驱动器

Python 3.x 将图形写入Google云存储而不是本地驱动器,python-3.x,matplotlib,google-cloud-platform,google-cloud-storage,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}'.

我想把用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行,印刷体_png filename_或_obj=open(filename_或_obj,'wb')

FileNotFoundError:[Errno 2]没有这样的文件或目录:“gs://skin\u cancer\u mnist/logs/20190116-195604/accurity\u loss\u graph.png”

(目录存在,我已选中)


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

您不能使用python
Open
函数直接将文件上载到Google云存储(这是
matplotlib.pyplot.savefig
在幕后使用的函数)。 相反,您应该使用。有关如何使用此库的详细信息,请选中此复选框。这将允许您操作文件并将其上载/下载到地面军事系统,以及其他功能

您必须导入此库才能使用它,您可以通过运行
pip install google cloud storage
来安装它,并将其作为
从google.cloud import storage
导入

同样,由于
plt.figure
是一个对象,而不是您想要上传的实际
.png
图像,因此您也不能直接将其上传到谷歌云存储

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

选项1:在本地保存图像,然后将其上载到谷歌云存储:

使用您的代码:

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")
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')
选项2:将图形的图像结果保存到变量中,然后将其作为字符串(字节)上传到GCS:

我发现下面的StackOverflow答案似乎可以将图形图像保存到
.png
字节字符串中,但我自己没有尝试过

同样,基于您的代码:

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")
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')

编辑:这两个选项都假设您运行脚本的环境已安装,并且已激活Google Cloud身份验证帐户(如果您没有,您可以检查该帐户以说明如何执行该操作)。

Joan的第二个选项不适用于我,我找到了一个适用于我的解决方案:

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)

我认为关键在于将文件保存在内存中,另请参见: