Repository: chainer/chainer

Issue:
Chainer 1.21.0: mnist example raises AttributeError: 'PlotReport' object has no attribute '_file_name'
I ran an example code train_mnist.py without matplotlib and got AttributeError.

1. create Anaconda environment
$ conda create -n testenv python=2.7

```
Fetching package metadata .......
Solving package specifications: ..........
Using Anaconda Cloud api site https://api.anaconda.org

The following NEW packages will be INSTALLED:

    openssl:    1.0.2k-0
    pip:        9.0.1-py27_1
    python:     2.7.13-0
    readline:   6.2-2
    setuptools: 27.2.0-py27_0
    sqlite:     3.13.0-0
    tk:         8.5.18-0
    wheel:      0.29.0-py27_0
    zlib:       1.2.8-3

```
2. install chainer with pip
$ pip install chainer

3. clone Chainer repository
$ git clone https://github.com/pfnet/chainer.git
$ cd chainer
$ git log

```
commit 6d2855c85c86cf655e7b87991ac353fa9f8d7603
Merge: 5f18ac0 10fb6ed
Author: Ryosuke Okuta <okuta@preferred.jp>
Date:   Wed Feb 15 10:18:25 2017 +0900

    Merge pull request #2273 from yuyu2172/missing-docs

    Include space2depth and depth2space to docs

```

4. run mnist example
$ cd examples/mnist/
$ python train_mnist.py -g 0

5. got error

```
GPU: 0
# unit: 1000
# Minibatch-size: 100
# epoch: 20

chainer/training/extensions/plot_report.py:27: UserWarning: matplotlib is not installed on your environment, so nothing will be plotted at this time. Please install matplotlib to plot figures.

  $ pip install matplotlib

  warnings.warn('matplotlib is not installed on your environment, '

Traceback (most recent call last):
  File "train_mnist.py", line 115, in <module>
    main()
  File "train_mnist.py", line 112, in main
    trainer.run()
  File "<secret>/python2.7/site-packages/chainer/training/trainer.py", line 298, in run
    entry.extension(self)
  File "<secret>/python2.7/site-packages/chainer/training/extensions/_snapshot.py", line 78, in snapshot
    _snapshot_object(trainer, trainer, filename.format(trainer), savefun)
  File "<secret>/python2.7/site-packages/chainer/training/extensions/_snapshot.py", line 88, in _snapshot_object
    savefun(tmppath, target)
  File "<secret>/python2.7/site-packages/chainer/serializers/npz.py", line 67, in save_npz
    s.save(obj)
  File "<secret>/python2.7/site-packages/chainer/serializer.py", line 69, in save
    obj.serialize(self)
  File "<secret>/python2.7/site-packages/chainer/training/trainer.py", line 318, in serialize
    entry.extension.serialize(s[name])
  File "<secret>/python2.7/site-packages/chainer/training/extensions/plot_report.py", line 150, in serialize
    serializer('_plot_{}'.format(self._file_name),
AttributeError: 'PlotReport' object has no attribute '_file_name'

```


Discussion:

Resolving patch:
diff --git a/chainer/training/extensions/plot_report.py b/chainer/training/extensions/plot_report.py
--- a/chainer/training/extensions/plot_report.py
+++ b/chainer/training/extensions/plot_report.py
@@ -76,9 +76,6 @@ def __init__(self, y_keys, x_key='iteration', trigger=(1, 'epoch'),
 
         _check_available()
 
-        if not _available:
-            return
-
         self._x_key = x_key
         if isinstance(y_keys, str):
             y_keys = (y_keys,)
@@ -92,6 +89,11 @@ def __init__(self, y_keys, x_key='iteration', trigger=(1, 'epoch'),
         self._init_summary()
         self._data = {k: [] for k in y_keys}
 
+    @staticmethod
+    def available(self):
+        _check_available()
+        return _available
+
     def __call__(self, trainer):
         if not _available:
             return
diff --git a/examples/mnist/train_mnist.py b/examples/mnist/train_mnist.py
--- a/examples/mnist/train_mnist.py
+++ b/examples/mnist/train_mnist.py
@@ -85,12 +85,14 @@ def main():
     trainer.extend(extensions.LogReport())
 
     # Save two plot images to the result dir
-    trainer.extend(
-        extensions.PlotReport(['main/loss', 'validation/main/loss'], 'epoch',
-                              file_name='loss.png'))
-    trainer.extend(
-        extensions.PlotReport(['main/accuracy', 'validation/main/accuracy'],
-                              'epoch', file_name='accuracy.png'))
+    if extensions.PlotReport.available():
+        trainer.extend(
+            extensions.PlotReport(['main/loss', 'validation/main/loss'],
+                                  'epoch', file_name='loss.png'))
+        trainer.extend(
+            extensions.PlotReport(
+                ['main/accuracy', 'validation/main/accuracy'],
+                'epoch', file_name='accuracy.png'))
 
     # Print selected entries of the log to stdout
     # Here "main" refers to the target link of the "main" optimizer again, and


Test patch: