materialsproject / pymatgen

Python Materials Genomics (pymatgen) is a robust materials analysis code that defines classes for structures and molecules with support for many electronic structure codes. It powers the Materials Project.
https://pymatgen.org
Other
1.51k stars 862 forks source link

electronic_structure.plotter.DosPlotter raises ValueError for some MP materials #210

Closed dwinston closed 9 years ago

dwinston commented 9 years ago

I'm getting a ValueError pertaining to numpy array shapes when trying to get the DOS plots for a couple of materials. Out of 500 sample materials, I found only two that fail to plot, so the problem may be upstream, e.g. the db data is misformatted. However, MPRester.get_dos_by_material_id succeeds in instantiating a pymatgen.electronic_structure.dos.CompleteDos, which should always be plottable.

Reproduction:

from pymatgen import MPRester
from pymatgen.electronic_structure.plotter import DosPlotter
culprits = ['mp-560581', 'mp-3318']

m = MPRester()
dos = m.get_dos_by_material_id('mp-3318')
dp = DosPlotter()
dp.add_dos_dict(dos.get_element_dos())
dp.get_plot() # ValueError: x and y must have same first dimension

Trace:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-40-65680dbbf86a> in <module>()
      7 dp = DosPlotter()
      8 dp.add_dos_dict(dos.get_element_dos())
----> 9 dp.get_plot() # ValueError: x and y must have same first dimension

/Users/dwinston/.virtualenvs/mp/lib/python2.7/site-packages/pymatgen/electronic_structure/plotter.pyc in get_plot(self, xlim, ylim)
    172             else:
    173                 ppl.plot(x, y, color=colors[i % ncolors],
--> 174                          label=str(key),linewidth=3)
    175             if not self.zero_at_efermi:
    176                 ylim = plt.ylim()

/Users/dwinston/.virtualenvs/mp/lib/python2.7/site-packages/prettyplotlib/colors.pyc in wrapper(*args, **kwargs)
     33     def wrapper(*args, **kwargs):
     34         with mpl.rc_context(rc=rcParams):
---> 35             return func(*args, **kwargs)
     36     return wrapper
     37 

/Users/dwinston/.virtualenvs/mp/lib/python2.7/site-packages/prettyplotlib/_plot.pyc in plot(*args, **kwargs)
     10     show_ticks = kwargs.pop('show_ticks', False)
     11 
---> 12     lines = ax.plot(*args, **kwargs)
     13     remove_chartjunk(ax, ['top', 'right'], show_ticks=show_ticks)
     14     return lines

/Users/dwinston/.virtualenvs/mp/lib/python2.7/site-packages/matplotlib-1.4.3-py2.7-macosx-10.10-x86_64.egg/matplotlib/axes/_axes.pyc in plot(self, *args, **kwargs)
   1371         lines = []
   1372 
-> 1373         for line in self._get_lines(*args, **kwargs):
   1374             self.add_line(line)
   1375             lines.append(line)

/Users/dwinston/.virtualenvs/mp/lib/python2.7/site-packages/matplotlib-1.4.3-py2.7-macosx-10.10-x86_64.egg/matplotlib/axes/_base.pyc in _grab_next_args(self, *args, **kwargs)
    302                 return
    303             if len(remaining) <= 3:
--> 304                 for seg in self._plot_args(remaining, kwargs):
    305                     yield seg
    306                 return

/Users/dwinston/.virtualenvs/mp/lib/python2.7/site-packages/matplotlib-1.4.3-py2.7-macosx-10.10-x86_64.egg/matplotlib/axes/_base.pyc in _plot_args(self, tup, kwargs)
    280             x = np.arange(y.shape[0], dtype=float)
    281 
--> 282         x, y = self._xy_from_xy(x, y)
    283 
    284         if self.command == 'plot':

/Users/dwinston/.virtualenvs/mp/lib/python2.7/site-packages/matplotlib-1.4.3-py2.7-macosx-10.10-x86_64.egg/matplotlib/axes/_base.pyc in _xy_from_xy(self, x, y)
    221         y = np.atleast_1d(y)
    222         if x.shape[0] != y.shape[0]:
--> 223             raise ValueError("x and y must have same first dimension")
    224         if x.ndim > 2 or y.ndim > 2:
    225             raise ValueError("x and y can be no greater than 2-D")

ValueError: x and y must have same first dimension
shyuep commented 9 years ago

This is really a data problem. I am not sure what is happening. But the energies has 581 elements and the densities has 601 elements. That cannot be the case.

Also, this seems to be non-spin-polarized, which is strange since we always do spin-polarized calculations. I suspect that the vasp run resulted in a bad DOS (e.g., one of the ***\ values type), which is non-fatal in parsing, but is fatal when trying to plot it.

The DOS object itself does not perform a check on the length of the arrays.

In conclusion, someone needs to trace back the original data source. It is not a pymatgen problem. Closing this issue.