python—使用matplotlib和boto将绘图从内存上载到s3

python—使用matplotlib和boto将绘图从内存上载到s3,python,python-3.x,matplotlib,amazon-s3,boto,Python,Python 3.x,Matplotlib,Amazon S3,Boto,这是我的工作脚本,用于生成绘图,将其本地保存到磁盘,上载到S3并删除文件: plt.figure(figsize=(6,6)) plt.plot(x, y, 'bo') plt.savefig('file_location') conn = boto.s3.connect_to_region( region_name=AWS_REGION, aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SE

这是我的工作脚本,用于生成绘图,将其本地保存到磁盘,上载到S3并删除文件:

plt.figure(figsize=(6,6))
plt.plot(x, y, 'bo')
plt.savefig('file_location')

conn = boto.s3.connect_to_region(
    region_name=AWS_REGION,
    aws_access_key_id=AWS_ACCESS_KEY_ID,
    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
    calling_format=boto.s3.connection.OrdinaryCallingFormat()
    )
bucket = conn.get_bucket('bucket_name')
k = Key(bucket)
k.key = 'file_name'
k.set_contents_from_filename('file_location')

os.remove(file_location)
我想要的是跳过磁盘写入,直接从内存上传绘图


如何实现这一目标,有什么建议吗?

综合起来:

img_data = io.BytesIO()
plt.savefig(img_data, format='png')
img_data.seek(0)

s3 = boto3.resource('s3')
bucket = s3.Bucket(BUCKET_NAME)
bucket.put_object(Body=img_data, ContentType='image/png', Key=KEY)

谢谢@padraic cunningham和@guyb7的提示

保存到
io.BytesIO()
f=io.BytesIO(),plt.savefig(f)
太好了,谢谢!为了以后上传,我只需调用
f.seek(0)
,然后从文件(f)中设置内容。是的,指针将在写入后结束。上载的图像对我来说是空的:(但我正在尝试上载实际图像,而不是plt图形…这会有区别吗?我如何读取图像?我尝试了img=skio.imread(io.BytesIO(obj.get()['Body'].read()),但我得到一个错误:“找不到在“i”模式下读取指定文件的格式。@Raksha请尝试以下操作:将plt.savefig(img_数据,format='png')替换为plt.imsave(img_数据,my_img)其中my_img是您的图像数据。如果上传的图像如@Raksha所述为空。请检查此答案。是否有人知道此解决方案在我使用AWS signedURL打开它时为什么会裁剪绘图?
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_agg import FigureCanvasAgg
import boto3
import io

# some random plotting. We need the figure object later
fig, ax = plt.subplots(1,1,figsize=(6,6))
ax.plot(np.linspace(0,1,50),
        np.random.normal(0.5,0.5,50))


canvas = FigureCanvas(fig) # renders figure onto canvas
imdata = io.BytesIO() # prepares in-memory binary stream buffer (think of this as a txt file but purely in memory)
canvas.print_png(imdata) # writes canvas object as a png file to the buffer. You can also use print_jpg, alternatively

s3 = boto3.resource('s3',
                    aws_access_key_id='your access key id',
                    aws_secret_access_key='your secret access key',
                    region_name='us-east-1') # or whatever region your s3 is in

s3.Object('yourbucket','picture.png').put(Body=imdata.getvalue(),
                                          ContentType='image/png') 
# this makes a new object in the bucket and puts the file in the bucket
# ContentType parameter makes sure resulting object is of a 'image/png' type and not a downloadable 'binary/octet-stream'

s3.ObjectAcl('yourbucket','picture.png').put(ACL='public-read')
# include this last line if you find the url for the image to be inaccessible