prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Matplotlib 3.3.0 Breaks _png
  <!--To help us understand and resolve your issue, please fill out the form to
  the best of your ability.-->
  <!--You can feel free to delete the sections that do not apply.-->
  
  ### Bug report
  
  **Bug summary**
  
  Matplotlib 3.3.0 removed the internal `_png` module, which breaks
  https://github.com/yt-project/yt/blob/yt-3.6.0/yt/utilities/png_writer.py#L13
  
  See the last mention in https://matplotlib.org/3.3.0/api/api_changes.html#matplotlib-now-uses-pillow-to-save-and-read-pngs
  
  **Code for reproduction**
  
  Just saw this on our CI:
  https://travis-ci.com/github/ECP-WarpX/WarpX/jobs/361956903
  
  MPL 3.3.0 was release about 5hrs ago.
  https://github.com/matplotlib/matplotlib/releases/tag/v3.3.0
  
  **Actual outcome**
  
  ```
  File "/home/travis/.local/lib/python3.6/site-packages/yt/utilities/png_writer.py", line 13, in <module>
      import matplotlib._png as _png
  ModuleNotFoundError: No module named 'matplotlib._png'
  ```
  
  **Expected outcome**
  
  :-)
  
  **Version Information**
  <!--Please specify your platform and versions of the relevant libraries you are
  using:-->
    * Operating System: Ubuntu 18.04
    * Python Version: 3.6
    * yt version: 3.6.0
  
  Installed via `python -m pip install --upgrade cmake matplotlib mpi4py numpy scipy yt`.
  
  **Work-Around**
  
  Downgrade matplotlib via `python -m pip install --upgrade matplotlib==3.2.2`.
  
  Exact details:
  - https://travis-ci.com/github/ECP-WarpX/WarpX/jobs/361956903
  - https://github.com/ECP-WarpX/WarpX/blob/384c6ab9a864d430868a39a065f4a1d4426231af/.travis.yml#L30-L31
  
  
  </issue>
  <code>
  [start of yt/utilities/png_writer.py]
  1 from io import BytesIO
  2 
  3 import matplotlib._png as _png
  4 
  5 
  6 def call_png_write_png(buffer, width, height, fileobj, dpi):
  7     _png.write_png(buffer, fileobj, dpi)
  8 
  9 
  10 def write_png(buffer, filename, dpi=100):
  11     width = buffer.shape[1]
  12     height = buffer.shape[0]
  13     with open(filename, "wb") as fileobj:
  14         call_png_write_png(buffer, width, height, fileobj, dpi)
  15 
  16 
  17 def write_png_to_string(buffer, dpi=100, gray=0):
  18     width = buffer.shape[1]
  19     height = buffer.shape[0]
  20     fileobj = BytesIO()
  21     call_png_write_png(buffer, width, height, fileobj, dpi)
  22     png_str = fileobj.getvalue()
  23     fileobj.close()
  24     return png_str
  25
  [end of yt/utilities/png_writer.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/yt/utilities/png_writer.py b/yt/utilities/png_writer.py
  --- a/yt/utilities/png_writer.py
  +++ b/yt/utilities/png_writer.py
  @@ -1,24 +1,29 @@
   from io import BytesIO
   
  -import matplotlib._png as _png
  +try:
  +    # matplotlib switched from an internal submodule _png to using pillow (PIL)
  +    # between v3.1.0 and v3.3.0
  +    # So PIL should be available on any system where matplotlib._png doesn't exist
  +    import matplotlib._png as _png
  +except ImportError:
  +    from PIL import Image
   
   
  -def call_png_write_png(buffer, width, height, fileobj, dpi):
  -    _png.write_png(buffer, fileobj, dpi)
  +def call_png_write_png(buffer, fileobj, dpi):
  +    try:
  +        _png.write_png(buffer, fileobj, dpi)
  +    except NameError:
  +        Image.fromarray(buffer).save(fileobj, dpi=(dpi, dpi))
   
   
   def write_png(buffer, filename, dpi=100):
  -    width = buffer.shape[1]
  -    height = buffer.shape[0]
       with open(filename, "wb") as fileobj:
  -        call_png_write_png(buffer, width, height, fileobj, dpi)
  +        call_png_write_png(buffer, fileobj, dpi)
   
   
  -def write_png_to_string(buffer, dpi=100, gray=0):
  -    width = buffer.shape[1]
  -    height = buffer.shape[0]
  +def write_png_to_string(buffer, dpi=100):
       fileobj = BytesIO()
  -    call_png_write_png(buffer, width, height, fileobj, dpi)
  +    call_png_write_png(buffer, fileobj, dpi)
       png_str = fileobj.getvalue()
       fileobj.close()
       return png_str
  
verification_info: {"golden_diff": "diff --git a/yt/utilities/png_writer.py b/yt/utilities/png_writer.py\n--- a/yt/utilities/png_writer.py\n+++ b/yt/utilities/png_writer.py\n@@ -1,24 +1,29 @@\n from io import BytesIO\n \n-import matplotlib._png as _png\n+try:\n+    # matplotlib switched from an internal submodule _png to using pillow (PIL)\n+    # between v3.1.0 and v3.3.0\n+    # So PIL should be available on any system where matplotlib._png doesn't exist\n+    import matplotlib._png as _png\n+except ImportError:\n+    from PIL import Image\n \n \n-def call_png_write_png(buffer, width, height, fileobj, dpi):\n-    _png.write_png(buffer, fileobj, dpi)\n+def call_png_write_png(buffer, fileobj, dpi):\n+    try:\n+        _png.write_png(buffer, fileobj, dpi)\n+    except NameError:\n+        Image.fromarray(buffer).save(fileobj, dpi=(dpi, dpi))\n \n \n def write_png(buffer, filename, dpi=100):\n-    width = buffer.shape[1]\n-    height = buffer.shape[0]\n     with open(filename, \"wb\") as fileobj:\n-        call_png_write_png(buffer, width, height, fileobj, dpi)\n+        call_png_write_png(buffer, fileobj, dpi)\n \n \n-def write_png_to_string(buffer, dpi=100, gray=0):\n-    width = buffer.shape[1]\n-    height = buffer.shape[0]\n+def write_png_to_string(buffer, dpi=100):\n     fileobj = BytesIO()\n-    call_png_write_png(buffer, width, height, fileobj, dpi)\n+    call_png_write_png(buffer, fileobj, dpi)\n     png_str = fileobj.getvalue()\n     fileobj.close()\n     return png_str\n", "issue": "Matplotlib 3.3.0 Breaks _png\n<!--To help us understand and resolve your issue, please fill out the form to\r\nthe best of your ability.-->\r\n<!--You can feel free to delete the sections that do not apply.-->\r\n\r\n### Bug report\r\n\r\n**Bug summary**\r\n\r\nMatplotlib 3.3.0 removed the internal `_png` module, which breaks\r\nhttps://github.com/yt-project/yt/blob/yt-3.6.0/yt/utilities/png_writer.py#L13\r\n\r\nSee the last mention in https://matplotlib.org/3.3.0/api/api_changes.html#matplotlib-now-uses-pillow-to-save-and-read-pngs\r\n\r\n**Code for reproduction**\r\n\r\nJust saw this on our CI:\r\nhttps://travis-ci.com/github/ECP-WarpX/WarpX/jobs/361956903\r\n\r\nMPL 3.3.0 was release about 5hrs ago.\r\nhttps://github.com/matplotlib/matplotlib/releases/tag/v3.3.0\r\n\r\n**Actual outcome**\r\n\r\n```\r\nFile \"/home/travis/.local/lib/python3.6/site-packages/yt/utilities/png_writer.py\", line 13, in <module>\r\n    import matplotlib._png as _png\r\nModuleNotFoundError: No module named 'matplotlib._png'\r\n```\r\n\r\n**Expected outcome**\r\n\r\n:-)\r\n\r\n**Version Information**\r\n<!--Please specify your platform and versions of the relevant libraries you are\r\nusing:-->\r\n  * Operating System: Ubuntu 18.04\r\n  * Python Version: 3.6\r\n  * yt version: 3.6.0\r\n\r\nInstalled via `python -m pip install --upgrade cmake matplotlib mpi4py numpy scipy yt`.\r\n\r\n**Work-Around**\r\n\r\nDowngrade matplotlib via `python -m pip install --upgrade matplotlib==3.2.2`.\r\n\r\nExact details:\r\n- https://travis-ci.com/github/ECP-WarpX/WarpX/jobs/361956903\r\n- https://github.com/ECP-WarpX/WarpX/blob/384c6ab9a864d430868a39a065f4a1d4426231af/.travis.yml#L30-L31\r\n\n", "before_files": [{"content": "from io import BytesIO\n\nimport matplotlib._png as _png\n\n\ndef call_png_write_png(buffer, width, height, fileobj, dpi):\n    _png.write_png(buffer, fileobj, dpi)\n\n\ndef write_png(buffer, filename, dpi=100):\n    width = buffer.shape[1]\n    height = buffer.shape[0]\n    with open(filename, \"wb\") as fileobj:\n        call_png_write_png(buffer, width, height, fileobj, dpi)\n\n\ndef write_png_to_string(buffer, dpi=100, gray=0):\n    width = buffer.shape[1]\n    height = buffer.shape[0]\n    fileobj = BytesIO()\n    call_png_write_png(buffer, width, height, fileobj, dpi)\n    png_str = fileobj.getvalue()\n    fileobj.close()\n    return png_str\n", "path": "yt/utilities/png_writer.py"}]}