title: Writing matplotlib figure to a buffer, then reading as a file for embedding an image in a PDF
body: <p>I'm trying to save several matplotlib figures into specific locations in a PDF being created with FPDF. I'd prefer not to have to dump these figures to files and then pull them back in.  The better solution seems to be writing them to a buffer, then reading them back in, but I'm not sure that's possible.</p>
  
  <p>Simplified code:</p>
  
  <pre><code>import pandas as pd
  import matplotlib.pyplot as plt
  from fpdf import FPDF
  from io import BytesIO
  import base64
  
  # create figure
  fig = plt.figure()
  
  # add plot
  ax = pd.Series( [1,3,2] ).plot()
  
  # create bytesio object
  bio = BytesIO()        
  
  # save figure to bytesio
  fig.savefig(bio, format="png", bbox_inches='tight')
  
  # this works to save the figure to a file
  with open("myfile.png", "wb") as file:
      file.write(bio.getvalue())
  
  # create a PDF and set some attributes    
  pdf = FPDF(orientation="L", unit="in", format="letter")
  pdf.set_font('Arial', 'B', 14)
  pdf.add_page()
  
  # try to read the bytesio object as though it's a file
  # pdf.image() expects a file name or a URL: https://pyfpdf.readthedocs.io/en/latest/reference/image/index.html
  # trying to create a data url with the base64-encoded data inside it
  
  pdf.image( name='data://image/png;base64,' + base64.b64encode(bio.getvalue()).decode() , x=1, y=1, w=3.5, type='png')
  
  # save pdf
  pdf.output("mypdf.pdf")
  </code></pre>
  
  <p>Full stack trace:</p>
  
  <pre><code>---------------------------------------------------------------------------
  FileNotFoundError                         Traceback (most recent call last)
  &lt;ipython-input-17-0ec65d0f583e&gt; in &lt;module&gt;()
       30 # trying to create a data url with the base64-encoded data inside it
       31 
  ---&gt; 32 pdf.image( name='data://image/png;base64,' + base64.b64encode(bio.getvalue()).decode() , x=1, y=1, w=3.5, type='png')
       33 
       34 # save pdf
  
  ~\AppData\Local\Continuum\anaconda3\lib\site-packages\fpdf\fpdf.py in wrapper(self, *args, **kwargs)
      148                 self.error("No page open, you need to call add_page() first")
      149             else:
  --&gt; 150                 return fn(self, *args, **kwargs)
      151         return wrapper
      152 
  
  ~\AppData\Local\Continuum\anaconda3\lib\site-packages\fpdf\fpdf.py in image(self, name, x, y, w, h, type, link)
      969                 info=self._parsejpg(name)
      970             elif(type=='png'):
  --&gt; 971                 info=self._parsepng(name)
      972             else:
      973                 #Allow for additional formats
  
  ~\AppData\Local\Continuum\anaconda3\lib\site-packages\fpdf\fpdf.py in _parsepng(self, name)
     1770                f = urlopen(name)
     1771         else:
  -&gt; 1772             f=open(name,'rb')
     1773         if(not f):
     1774             self.error("Can't open image file: "+name)
  
  FileNotFoundError: [Errno 2] No such file or directory: 'data://image/png;base64,iVBORw0KGgoAAAANSU  #snipped for length#
  </code></pre>
  
  <p>Since pdf.image() can take a URL, I'd like to construct a data URL that doesn't actually try to open up a file.  It would be like embedding an image inline in an  HTML page. That sort of idea.  I've tried several iterations of getvalue() and encode() and decode(), but I'm not getting the right combination.</p>
  
  <p>I am successfully writing to a file in this example to make sure my BytesIO object has the right data in it, but dumping it into pdf.image() is not working.</p>