diff --git a/scripts/Muon/GUI/ElementalAnalysis/PeriodicTable/periodic_table.py b/scripts/Muon/GUI/ElementalAnalysis/PeriodicTable/periodic_table.py
new file mode 100644
index 0000000000000000000000000000000000000000..0e4e4a9f3ab40eb396f36fdc83f31fa864d23131
--- /dev/null
+++ b/scripts/Muon/GUI/ElementalAnalysis/PeriodicTable/periodic_table.py
@@ -0,0 +1,724 @@
+from collections import OrderedDict
+import logging
+from PyQt4 import QtCore
+from PyQt4 import QtGui as qt
+
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2004-2018 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+__authors__ = ["E. Papillon", "V.A. Sole", "P. Knobel"]
+__license__ = "MIT"
+__date__ = "26/01/2017"
+
+_logger = logging.getLogger(__name__)
+
+#             Symbol  Atomic Number   col row  name  mass subcategory
+_elements = [("H", 1, 1, 1, "hydrogen", 1.00800, "diatomic nonmetal"),
+             ("He", 2, 18, 1, "helium", 4.0030, "noble gas"),
+             ("Li", 3, 1, 2, "lithium", 6.94000, "alkali metal"),
+             ("Be", 4, 2, 2, "beryllium", 9.01200, "alkaline earth metal"),
+             ("B", 5, 13, 2, "boron", 10.8110, "metalloid"),
+             ("C", 6, 14, 2, "carbon", 12.0100, "polyatomic nonmetal"),
+             ("N", 7, 15, 2, "nitrogen", 14.0080, "diatomic nonmetal"),
+             ("O", 8, 16, 2, "oxygen", 16.0000, "diatomic nonmetal"),
+             ("F", 9, 17, 2, "fluorine", 19.0000, "diatomic nonmetal"),
+             ("Ne", 10, 18, 2, "neon", 20.1830, "noble gas"),
+             ("Na", 11, 1, 3, "sodium", 22.9970, "alkali metal"),
+             ("Mg", 12, 2, 3, "magnesium", 24.3200, "alkaline earth metal"),
+             ("Al", 13, 13, 3, "aluminium", 26.9700, "post transition metal"),
+             ("Si", 14, 14, 3, "silicon", 28.0860, "metalloid"),
+             ("P", 15, 15, 3, "phosphorus", 30.9750, "polyatomic nonmetal"),
+             ("S", 16, 16, 3, "sulphur", 32.0660, "polyatomic nonmetal"),
+             ("Cl", 17, 17, 3, "chlorine", 35.4570, "diatomic nonmetal"),
+             ("Ar", 18, 18, 3, "argon", 39.9440, "noble gas"),
+             ("K", 19, 1, 4, "potassium", 39.1020, "alkali metal"),
+             ("Ca", 20, 2, 4, "calcium", 40.0800, "alkaline earth metal"),
+             ("Sc", 21, 3, 4, "scandium", 44.9600, "transition metal"),
+             ("Ti", 22, 4, 4, "titanium", 47.9000, "transition metal"),
+             ("V", 23, 5, 4, "vanadium", 50.9420, "transition metal"),
+             ("Cr", 24, 6, 4, "chromium", 51.9960, "transition metal"),
+             ("Mn", 25, 7, 4, "manganese", 54.9400, "transition metal"),
+             ("Fe", 26, 8, 4, "iron", 55.8500, "transition metal"),
+             ("Co", 27, 9, 4, "cobalt", 58.9330, "transition metal"),
+             ("Ni", 28, 10, 4, "nickel", 58.6900, "transition metal"),
+             ("Cu", 29, 11, 4, "copper", 63.5400, "transition metal"),
+             ("Zn", 30, 12, 4, "zinc", 65.3800, "transition metal"),
+             ("Ga", 31, 13, 4, "gallium", 69.7200, "post transition metal"),
+             ("Ge", 32, 14, 4, "germanium", 72.5900, "metalloid"),
+             ("As", 33, 15, 4, "arsenic", 74.9200, "metalloid"),
+             ("Se", 34, 16, 4, "selenium", 78.9600, "polyatomic nonmetal"),
+             ("Br", 35, 17, 4, "bromine", 79.9200, "diatomic nonmetal"),
+             ("Kr", 36, 18, 4, "krypton", 83.8000, "noble gas"),
+             ("Rb", 37, 1, 5, "rubidium", 85.4800, "alkali metal"),
+             ("Sr", 38, 2, 5, "strontium", 87.6200, "alkaline earth metal"),
+             ("Y", 39, 3, 5, "yttrium", 88.9050, "transition metal"),
+             ("Zr", 40, 4, 5, "zirconium", 91.2200, "transition metal"),
+             ("Nb", 41, 5, 5, "niobium", 92.9060, "transition metal"),
+             ("Mo", 42, 6, 5, "molybdenum", 95.9500, "transition metal"),
+             ("Tc", 43, 7, 5, "technetium", 99.0000, "transition metal"),
+             ("Ru", 44, 8, 5, "ruthenium", 101.0700, "transition metal"),
+             ("Rh", 45, 9, 5, "rhodium", 102.9100, "transition metal"),
+             ("Pd", 46, 10, 5, "palladium", 106.400, "transition metal"),
+             ("Ag", 47, 11, 5, "silver", 107.880, "transition metal"),
+             ("Cd", 48, 12, 5, "cadmium", 112.410, "transition metal"),
+             ("In", 49, 13, 5, "indium", 114.820, "post transition metal"),
+             ("Sn", 50, 14, 5, "tin", 118.690, "post transition metal"),
+             ("Sb", 51, 15, 5, "antimony", 121.760, "metalloid"),
+             ("Te", 52, 16, 5, "tellurium", 127.600, "metalloid"),
+             ("I", 53, 17, 5, "iodine", 126.910, "diatomic nonmetal"),
+             ("Xe", 54, 18, 5, "xenon", 131.300, "noble gas"),
+             ("Cs", 55, 1, 6, "caesium", 132.910, "alkali metal"),
+             ("Ba", 56, 2, 6, "barium", 137.360, "alkaline earth metal"),
+             ("La", 57, 3, 6, "lanthanum", 138.920, "lanthanide"),
+             ("Ce", 58, 4, 9, "cerium", 140.130, "lanthanide"),
+             ("Pr", 59, 5, 9, "praseodymium", 140.920, "lanthanide"),
+             ("Nd", 60, 6, 9, "neodymium", 144.270, "lanthanide"),
+             ("Pm", 61, 7, 9, "promethium", 147.000, "lanthanide"),
+             ("Sm", 62, 8, 9, "samarium", 150.350, "lanthanide"),
+             ("Eu", 63, 9, 9, "europium", 152.000, "lanthanide"),
+             ("Gd", 64, 10, 9, "gadolinium", 157.260, "lanthanide"),
+             ("Tb", 65, 11, 9, "terbium", 158.930, "lanthanide"),
+             ("Dy", 66, 12, 9, "dysprosium", 162.510, "lanthanide"),
+             ("Ho", 67, 13, 9, "holmium", 164.940, "lanthanide"),
+             ("Er", 68, 14, 9, "erbium", 167.270, "lanthanide"),
+             ("Tm", 69, 15, 9, "thulium", 168.940, "lanthanide"),
+             ("Yb", 70, 16, 9, "ytterbium", 173.040, "lanthanide"),
+             ("Lu", 71, 17, 9, "lutetium", 174.990, "lanthanide"),
+             ("Hf", 72, 4, 6, "hafnium", 178.500, "transition metal"),
+             ("Ta", 73, 5, 6, "tantalum", 180.950, "transition metal"),
+             ("W", 74, 6, 6, "tungsten", 183.920, "transition metal"),
+             ("Re", 75, 7, 6, "rhenium", 186.200, "transition metal"),
+             ("Os", 76, 8, 6, "osmium", 190.200, "transition metal"),
+             ("Ir", 77, 9, 6, "iridium", 192.200, "transition metal"),
+             ("Pt", 78, 10, 6, "platinum", 195.090, "transition metal"),
+             ("Au", 79, 11, 6, "gold", 197.200, "transition metal"),
+             ("Hg", 80, 12, 6, "mercury", 200.610, "transition metal"),
+             ("Tl", 81, 13, 6, "thallium", 204.390, "post transition metal"),
+             ("Pb", 82, 14, 6, "lead", 207.210, "post transition metal"),
+             ("Bi", 83, 15, 6, "bismuth", 209.000, "post transition metal"),
+             ("Po", 84, 16, 6, "polonium", 209.000, "post transition metal"),
+             ("At", 85, 17, 6, "astatine", 210.000, "metalloid"),
+             ("Rn", 86, 18, 6, "radon", 222.000, "noble gas"),
+             ("Fr", 87, 1, 7, "francium", 223.000, "alkali metal"),
+             ("Ra", 88, 2, 7, "radium", 226.000, "alkaline earth metal"),
+             ("Ac", 89, 3, 7, "actinium", 227.000, "actinide"),
+             ("Th", 90, 4, 10, "thorium", 232.000, "actinide"),
+             ("Pa", 91, 5, 10, "proactinium", 231.03588, "actinide"),
+             ("U", 92, 6, 10, "uranium", 238.070, "actinide"),
+             ("Np", 93, 7, 10, "neptunium", 237.000, "actinide"),
+             ("Pu", 94, 8, 10, "plutonium", 239.100, "actinide"),
+             ("Am", 95, 9, 10, "americium", 243, "actinide"),
+             ("Cm", 96, 10, 10, "curium", 247, "actinide"),
+             ("Bk", 97, 11, 10, "berkelium", 247, "actinide"),
+             ("Cf", 98, 12, 10, "californium", 251, "actinide"),
+             ("Es", 99, 13, 10, "einsteinium", 252, "actinide"),
+             ("Fm", 100, 14, 10, "fermium", 257, "actinide"),
+             ("Md", 101, 15, 10, "mendelevium", 258, "actinide"),
+             ("No", 102, 16, 10, "nobelium", 259, "actinide"),
+             ("Lr", 103, 17, 10, "lawrencium", 262, "actinide"),
+             ("Rf", 104, 4, 7, "rutherfordium", 261, "transition metal"),
+             ("Db", 105, 5, 7, "dubnium", 262, "transition metal"),
+             ("Sg", 106, 6, 7, "seaborgium", 266, "transition metal"),
+             ("Bh", 107, 7, 7, "bohrium", 264, "transition metal"),
+             ("Hs", 108, 8, 7, "hassium", 269, "transition metal"),
+             ("Mt", 109, 9, 7, "meitnerium", 268)]
+
+
+class PeriodicTableItem(object):
+    """Periodic table item, used as generic item in :class:`PeriodicTable`,
+    :class:`PeriodicCombo` and  :class:`PeriodicList`.
+
+    This implementation stores the minimal amount of information needed by the
+    widgets:
+
+        - atomic symbol
+        - atomic number
+        - element name
+        - atomic mass
+        - column of element in periodic table
+        - row of element in periodic table
+
+    You can subclass this class to add additional information.
+
+    :param str symbol: Atomic symbol (e.g. H, He, Li...)
+    :param int Z: Proton number
+    :param int col: 1-based column index of element in periodic table
+    :param int row: 1-based row index of element in periodic table
+    :param str name: PeriodicTableItem name ("hydrogen", ...)
+    :param float mass: Atomic mass (gram per mol)
+    :param str subcategory: Subcategory, based on physical properties
+        (e.g. "alkali metal", "noble gas"...)
+    """
+
+    def __init__(self, symbol, Z, col, row, name, mass,
+                 subcategory=""):
+        self.symbol = symbol
+        """Atomic symbol (e.g. H, He, Li...)"""
+        self.Z = Z
+        """Atomic number (Proton number)"""
+        self.col = col
+        """1-based column index of element in periodic table"""
+        self.row = row
+        """1-based row index of element in periodic table"""
+        self.name = name
+        """PeriodicTableItem name ("hydrogen", ...)"""
+        self.mass = mass
+        """Atomic mass (gram per mol)"""
+        self.subcategory = subcategory
+        """Subcategory, based on physical properties
+        (e.g. "alkali metal", "noble gas"...)"""
+
+    # pymca compatibility (elements used to be stored as a list of lists)
+    def __getitem__(self, idx):
+        if idx == 6:
+            _logger.warning("density not implemented in silx, returning 0.")
+
+        ret = [self.symbol, self.Z,
+               self.col, self.row,
+               self.name, self.mass,
+               0.]
+        return ret[idx]
+
+    def __len__(self):
+        return 6
+
+
+class ColoredPeriodicTableItem(PeriodicTableItem):
+    """:class:`PeriodicTableItem` with an added :attr:`bgcolor`.
+    The background color can be passed as a parameter to the constructor.
+    If it is not specified, it will be defined based on
+    :attr:`subcategory`.
+
+    :param str bgcolor: Custom background color for element in
+        periodic table, as a RGB string *#RRGGBB*"""
+    COLORS = {
+        "diatomic nonmetal": "#7FFF00",  # chartreuse
+        "noble gas": "#00FFFF",  # cyan
+        "alkali metal": "#FFE4B5",  # Moccasin
+        "alkaline earth metal": "#FFA500",  # orange
+        "polyatomic nonmetal": "#7FFFD4",  # aquamarine
+        "transition metal": "#FFA07A",  # light salmon
+        "metalloid": "#8FBC8F",  # Dark Sea Green
+        "post transition metal": "#D3D3D3",  # light gray
+        "lanthanide": "#FFB6C1",  # light pink
+        "actinide": "#F08080",  # Light Coral
+        "": "#FFFFFF"  # white
+    }
+    """Dictionary defining RGB colors for each subcategory."""
+
+    def __init__(self, symbol, Z, col, row, name, mass,
+                 subcategory="", bgcolor=None):
+        PeriodicTableItem.__init__(self, symbol, Z, col, row, name, mass,
+                                   subcategory)
+
+        self.bgcolor = self.COLORS.get(subcategory, "#FFFFFF")
+        """Background color of element in the periodic table,
+        based on its subcategory. This should be a string of a hexadecimal
+        RGB code, with the format *#RRGGBB*.
+        If the subcategory is unknown, use white (*#FFFFFF*)
+        """
+
+        # possible custom color
+        if bgcolor is not None:
+            self.bgcolor = bgcolor
+
+
+_defaultTableItems = [ColoredPeriodicTableItem(*info) for info in _elements]
+
+
+class _ElementButton(qt.QPushButton):
+    """Atomic element button, used as a cell in the periodic table
+    """
+    sigElementEnter = QtCore.pyqtSignal(object)
+    """Signal emitted as the cursor enters the widget"""
+    sigElementLeave = QtCore.pyqtSignal(object)
+    """Signal emitted as the cursor leaves the widget"""
+    sigElementClicked = QtCore.pyqtSignal(object)
+    """Signal emitted when the widget is clicked"""
+
+    def __init__(self, item, parent=None):
+        """
+
+        :param parent: Parent widget
+        :param PeriodicTableItem item: :class:`PeriodicTableItem` object
+        """
+        qt.QPushButton.__init__(self, parent)
+
+        self.item = item
+        """:class:`PeriodicTableItem` object represented by this button"""
+
+        self.setText(item.symbol)
+        self.setFlat(1)
+        self.setCheckable(0)
+
+        self.setSizePolicy(qt.QSizePolicy(qt.QSizePolicy.Expanding,
+                                          qt.QSizePolicy.Expanding))
+
+        self.selected = False
+        self.current = False
+
+        # selection colors
+        self.selected_color = qt.QColor(QtCore.Qt.yellow)
+        self.current_color = qt.QColor(QtCore.Qt.gray)
+        self.selected_current_color = qt.QColor(QtCore.Qt.darkYellow)
+
+        # element colors
+
+        if hasattr(item, "bgcolor"):
+            self.bgcolor = qt.QColor(item.bgcolor)
+        else:
+            self.bgcolor = qt.QColor("#FFFFFF")
+
+        self.brush = qt.QBrush()
+        self.__setBrush()
+
+        self.clicked.connect(self.clickedSlot)
+
+    def sizeHint(self):
+        return QtCore.QSize(40, 40)
+
+    def setCurrent(self, b):
+        """Set this element button as current.
+        Multiple buttons can be selected.
+
+        :param b: boolean
+        """
+        self.current = b
+        self.__setBrush()
+
+    def isCurrent(self):
+        """
+        :return: True if element button is current
+        """
+        return self.current
+
+    def isSelected(self):
+        """
+        :return: True if element button is selected
+        """
+        return self.selected
+
+    def setSelected(self, b):
+        """Set this element button as selected.
+        Only a single button can be selected.
+
+        :param b: boolean
+        """
+        self.selected = b
+        self.__setBrush()
+
+    def __setBrush(self):
+        """Selected cells are yellow when not current.
+        The current cell is dark yellow when selected or grey when not
+        selected.
+        Other cells have no bg color by default, unless specified at
+        instantiation (:attr:`bgcolor`)"""
+        palette = self.palette()
+        # if self.current and self.selected:
+        #     self.brush = qt.QBrush(self.selected_current_color)
+        # el
+        if self.selected:
+            self.brush = qt.QBrush(self.selected_color)
+        # elif self.current:
+        #     self.brush = qt.QBrush(self.current_color)
+        elif self.bgcolor is not None:
+            self.brush = qt.QBrush(self.bgcolor)
+        else:
+            self.brush = qt.QBrush()
+        palette.setBrush(self.backgroundRole(),
+                         self.brush)
+        self.setPalette(palette)
+        self.update()
+
+    def paintEvent(self, pEvent):
+        # get button geometry
+        widgGeom = self.rect()
+        paintGeom = QtCore.QRect(widgGeom.left() + 1,
+                                 widgGeom.top() + 1,
+                                 widgGeom.width() - 2,
+                                 widgGeom.height() - 2)
+
+        # paint background color
+        painter = qt.QPainter(self)
+        if self.brush is not None:
+            painter.fillRect(paintGeom, self.brush)
+        # paint frame
+        pen = qt.QPen(QtCore.Qt.black)
+        pen.setWidth(1 if not self.isCurrent() else 5)
+        painter.setPen(pen)
+        painter.drawRect(paintGeom)
+        painter.end()
+        qt.QPushButton.paintEvent(self, pEvent)
+
+    def enterEvent(self, e):
+        """Emit a :attr:`sigElementEnter` signal and send a
+        :class:`PeriodicTableItem` object"""
+        self.sigElementEnter.emit(self.item)
+
+    def leaveEvent(self, e):
+        """Emit a :attr:`sigElementLeave` signal and send a
+        :class:`PeriodicTableItem` object"""
+        self.sigElementLeave.emit(self.item)
+
+    def clickedSlot(self):
+        """Emit a :attr:`sigElementClicked` signal and send a
+        :class:`PeriodicTableItem` object"""
+        self.sigElementClicked.emit(self.item)
+
+
+class PeriodicTable(qt.QWidget):
+    """Periodic Table widget
+
+    .. image:: img/PeriodicTable.png
+
+    The following example shows how to connect clicking to selection::
+
+         from silx.gui import qt
+         from silx.gui.widgets.PeriodicTable import PeriodicTable
+         app = qt.QApplication([])
+         pt = PeriodicTable()
+         pt.sigElementClicked.connect(pt.elementToggle)
+         pt.show()
+         app.exec_()
+
+    To print all selected elements each time a new element is selected::
+
+        def my_slot(item):
+            pt.elementToggle(item)
+            selected_elements = pt.getSelection()
+            for e in selected_elements:
+                print(e.symbol)
+
+        pt.sigElementClicked.connect(my_slot)
+
+    """
+    sigElementClicked = QtCore.pyqtSignal(object)
+    """When any element is clicked in the table, the widget emits
+    this signal and sends a :class:`PeriodicTableItem` object.
+    """
+
+    sigSelectionChanged = QtCore.pyqtSignal(object)
+    """When any element is selected/unselected in the table, the widget emits
+    this signal and sends a list of :class:`PeriodicTableItem` objects.
+
+    .. note::
+
+        To enable selection of elements, you must set *selectable=True*
+        when you instantiate the widget. Alternatively, you can also connect
+        :attr:`sigElementClicked` to :meth:`elementToggle` manually::
+
+            pt = PeriodicTable()
+            pt.sigElementClicked.connect(pt.elementToggle)
+
+
+    :param parent: parent QWidget
+    :param str name: Widget window title
+    :param elements: List of items (:class:`PeriodicTableItem` objects) to
+        be represented in the table. By default, take elements from
+        a predefined list with minimal information (symbol, atomic number,
+        name, mass).
+    :param bool selectable: If *True*, multiple elements can be
+        selected by clicking with the mouse. If *False* (default),
+        selection is only possible with method :meth:`setSelection`.
+    """
+
+    def __init__(self, parent=None, name="PeriodicTable", elements=None,
+                 selectable=False):
+        self.selectable = selectable
+        qt.QWidget.__init__(self, parent)
+        self.setWindowTitle(name)
+        self.gridLayout = qt.QGridLayout(self)
+        self.gridLayout.setContentsMargins(0, 0, 0, 0)
+        self.gridLayout.addItem(qt.QSpacerItem(0, 5), 7, 0)
+
+        for idx in range(10):
+            self.gridLayout.setRowStretch(idx, 3)
+        # row 8 (above lanthanoids  is empty)
+        self.gridLayout.setRowStretch(7, 2)
+
+        # Element information displayed when cursor enters a cell
+        self.eltLabel = qt.QLabel(self)
+        f = self.eltLabel.font()
+        f.setBold(1)
+        self.eltLabel.setFont(f)
+        self.eltLabel.setAlignment(QtCore.Qt.AlignHCenter)
+        self.gridLayout.addWidget(self.eltLabel, 1, 1, 3, 10)
+
+        self._eltCurrent = None
+        """Current :class:`_ElementButton` (last clicked)"""
+
+        self._eltButtons = OrderedDict()
+        """Dictionary of all :class:`_ElementButton`. Keys are the symbols
+        ("H", "He", "Li"...)"""
+
+        if elements is None:
+            elements = _defaultTableItems
+        # fill cells with elements
+        for elmt in elements:
+            self.__addElement(elmt)
+
+    def __addElement(self, elmt):
+        """Add one :class:`_ElementButton` widget into the grid,
+        connect its signals to interact with the cursor"""
+        b = _ElementButton(elmt, self)
+        b.setAutoDefault(False)
+
+        self._eltButtons[elmt.symbol] = b
+        self.gridLayout.addWidget(b, elmt.row, elmt.col)
+
+        b.sigElementEnter.connect(self.elementEnter)
+        b.sigElementLeave.connect(self._elementLeave)
+        b.sigElementClicked.connect(self._elementClicked)
+
+    def elementEnter(self, item):
+        """Update label with element info (e.g. "Nb(41) - niobium")
+        when mouse cursor hovers an element.
+
+        :param PeriodicTableItem item: Element entered by cursor
+        """
+        self.eltLabel.setText("%s(%d) - %s" % (item.symbol, item.Z, item.name))
+
+    def _elementLeave(self, item):
+        """Clear label when the cursor leaves the cell
+
+        :param PeriodicTableItem item: Element left
+        """
+        self.eltLabel.setText("")
+
+    def _elementClicked(self, item):
+        """Emit :attr:`sigElementClicked`,
+        toggle selected state of element
+
+        :param PeriodicTableItem item: Element clicked
+        """
+        if self._eltCurrent is not None:
+            self._eltCurrent.setCurrent(False)
+        self._eltButtons[item.symbol].setCurrent(True)
+        self._eltCurrent = self._eltButtons[item.symbol]
+        if self.selectable:
+            self.elementToggle(item)
+        self.sigElementClicked.emit(item)
+
+    def getSelection(self):
+        """Return a list of selected elements, as a list of :class:`PeriodicTableItem`
+        objects.
+
+        :return: Selected items
+        :rtype: List[PeriodicTableItem]
+        """
+        return [b.item for b in self._eltButtons.values() if b.isSelected()]
+
+    def setSelection(self, symbols):
+        """Set selected elements.
+
+        This causes the sigSelectionChanged signal
+        to be emitted, even if the selection didn't actually change.
+
+        :param List[str] symbols: List of symbols of elements to be selected
+            (e.g. *["Fe", "Hg", "Li"]*)
+        """
+        # accept list of PeriodicTableItems as input, because getSelection
+        # returns these objects and it makes sense to have getter and setter
+        # use same type of data
+        if isinstance(symbols[0], PeriodicTableItem):
+            symbols = [elmt.symbol for elmt in symbols]
+
+        for (e, b) in self._eltButtons.items():
+            b.setSelected(e in symbols)
+        self.sigSelectionChanged.emit(self.getSelection())
+
+    def setElementSelected(self, symbol, state):
+        """Modify *selected* status of a single element (select or unselect)
+
+        :param str symbol: PeriodicTableItem symbol to be selected
+        :param bool state: *True* to select, *False* to unselect
+        """
+        self._eltButtons[symbol].setSelected(state)
+        self.sigSelectionChanged.emit(self.getSelection())
+
+    def isElementSelected(self, symbol):
+        """Return *True* if element is selected, else *False*
+
+        :param str symbol: PeriodicTableItem symbol
+        :return: *True* if element is selected, else *False*
+        """
+        return self._eltButtons[symbol].isSelected()
+
+    def elementToggle(self, item):
+        """Toggle selected/unselected state for element
+
+        :param item: PeriodicTableItem object
+        """
+        b = self._eltButtons[item.symbol]
+        b.setSelected(not b.isSelected())
+        self.sigSelectionChanged.emit(self.getSelection())
+
+
+class PeriodicCombo(qt.QComboBox):
+    """
+    Combo list with all atomic elements of the periodic table
+
+    .. image:: img/PeriodicCombo.png
+
+    :param bool detailed: True (default) display element symbol, Z and name.
+        False display only element symbol and Z.
+    :param elements: List of items (:class:`PeriodicTableItem` objects) to
+        be represented in the table. By default, take elements from
+        a predefined list with minimal information (symbol, atomic number,
+        name, mass).
+    """
+    sigSelectionChanged = QtCore.pyqtSignal(object)
+    """Signal emitted when the selection changes. Send
+    :class:`PeriodicTableItem` object representing selected
+    element
+    """
+
+    def __init__(self, parent=None, detailed=True, elements=None):
+        qt.QComboBox.__init__(self, parent)
+
+        # add all elements from global list
+        if elements is None:
+            elements = _defaultTableItems
+        for i, elmt in enumerate(elements):
+            if detailed:
+                txt = "%2s (%d) - %s" % (elmt.symbol, elmt.Z, elmt.name)
+            else:
+                txt = "%2s (%d)" % (elmt.symbol, elmt.Z)
+            self.insertItem(i, txt)
+
+        self.currentIndexChanged[int].connect(self.__selectionChanged)
+
+    def __selectionChanged(self, idx):
+        """Emit :attr:`sigSelectionChanged`"""
+        self.sigSelectionChanged.emit(_defaultTableItems[idx])
+
+    def getSelection(self):
+        """Get selected element
+
+        :return: Selected element
+        :rtype: PeriodicTableItem
+        """
+        return _defaultTableItems[self.currentIndex()]
+
+    def setSelection(self, symbol):
+        """Set selected item in combobox by giving the atomic symbol
+
+        :param symbol: Symbol of element to be selected
+        """
+        # accept PeriodicTableItem for getter/setter consistency
+        if isinstance(symbol, PeriodicTableItem):
+            symbol = symbol.symbol
+        symblist = [elmt.symbol for elmt in _defaultTableItems]
+        self.setCurrentIndex(symblist.index(symbol))
+
+
+class PeriodicList(qt.QTreeWidget):
+    """List of atomic elements in a :class:`QTreeView`
+
+    .. image:: img/PeriodicList.png
+
+    :param QWidget parent: Parent widget
+    :param bool detailed: True (default) display element symbol, Z and name.
+        False display only element symbol and Z.
+    :param single: *True* for single element selection with mouse click,
+        *False* for multiple element selection mode.
+    """
+    sigSelectionChanged = QtCore.pyqtSignal(object)
+    """When any element is selected/unselected in the widget, it emits
+    this signal and sends a list of currently selected
+    :class:`PeriodicTableItem` objects.
+    """
+
+    def __init__(self, parent=None, detailed=True,
+                 single=False, elements=None):
+        qt.QTreeWidget.__init__(self, parent)
+
+        self.detailed = detailed
+
+        headers = ["Z", "Symbol"]
+        if detailed:
+            headers.append("Name")
+            self.setColumnCount(3)
+        else:
+            self.setColumnCount(2)
+        self.setHeaderLabels(headers)
+        self.header().setStretchLastSection(False)
+
+        self.setRootIsDecorated(0)
+        self.itemClicked.connect(self.__selectionChanged)
+        self.setSelectionMode(qt.QAbstractItemView.SingleSelection if single
+                              else qt.QAbstractItemView.ExtendedSelection)
+        self.__fill_widget(elements)
+        self.resizeColumnToContents(0)
+        self.resizeColumnToContents(1)
+        if detailed:
+            self.resizeColumnToContents(2)
+
+    def __fill_widget(self, elements):
+        """Fill tree widget with elements """
+        if elements is None:
+            elements = _defaultTableItems
+
+        self.tree_items = []
+
+        previous_item = None
+        for elmt in elements:
+            if previous_item is None:
+                item = qt.QTreeWidgetItem(self)
+            else:
+                item = qt.QTreeWidgetItem(self, previous_item)
+            item.setText(0, str(elmt.Z))
+            item.setText(1, elmt.symbol)
+            if self.detailed:
+                item.setText(2, elmt.name)
+            self.tree_items.append(item)
+            previous_item = item
+
+    def __selectionChanged(self, treeItem, column):
+        """Emit a :attr:`sigSelectionChanged` and send a list of
+        :class:`PeriodicTableItem` objects."""
+        self.sigSelectionChanged.emit(self.getSelection())
+
+    def getSelection(self):
+        """Get a list of selected elements, as a list of :class:`PeriodicTableItem`
+        objects.
+
+        :return: Selected elements
+        :rtype: List[PeriodicTableItem]"""
+        return [_defaultTableItems[idx] for idx in range(len(self.tree_items))
+                if self.tree_items[idx].isSelected()]
+
+    # setSelection is a bad name (name of a QTreeWidget method)
+    def setSelectedElements(self, symbolList):
+        """
+
+        :param symbolList: List of atomic symbols ["H", "He", "Li"...]
+            to be selected in the widget
+        """
+        # accept PeriodicTableItem for getter/setter consistency
+        if isinstance(symbolList[0], PeriodicTableItem):
+            symbolList = [elmt.symbol for elmt in symbolList]
+        for idx in range(len(self.tree_items)):
+            self.tree_items[idx].setSelected(
+                _defaultTableItems[idx].symbol in symbolList)
diff --git a/scripts/Muon/GUI/ElementalAnalysis/PeriodicTable/periodic_table_view.py b/scripts/Muon/GUI/ElementalAnalysis/PeriodicTable/periodic_table_view.py
index 00232742dff145122acbc8e31cfc4b77ce01b985..c1599fb429851f9565a300d70d6731a68a0e2a56 100644
--- a/scripts/Muon/GUI/ElementalAnalysis/PeriodicTable/periodic_table_view.py
+++ b/scripts/Muon/GUI/ElementalAnalysis/PeriodicTable/periodic_table_view.py
@@ -2,7 +2,7 @@ from __future__ import absolute_import
 
 from PyQt4 import QtCore, QtGui
 
-from silx.gui.widgets import PeriodicTable
+from Muon.GUI.ElementalAnalysis.PeriodicTable import periodic_table
 
 
 class PeriodicTableView(QtGui.QWidget):
@@ -12,7 +12,7 @@ class PeriodicTableView(QtGui.QWidget):
     def __init__(self, parent=None):
         super(PeriodicTableView, self).__init__(parent)
 
-        self.ptable = PeriodicTable.PeriodicTable(self, selectable=True)
+        self.ptable = periodic_table.PeriodicTable(self, selectable=True)
         self.ptable.sigElementClicked.connect(self.table_clicked)
         self.ptable.sigSelectionChanged.connect(self.table_changed)
 
diff --git a/scripts/test/Muon/PeriodicTableWidget_test.py b/scripts/test/Muon/PeriodicTableWidget_test.py
index 78b220d008bfbd6788d75b9dc29f4115628a510c..66a2bbce56c884d9d33e5914716821bd0135c258 100644
--- a/scripts/test/Muon/PeriodicTableWidget_test.py
+++ b/scripts/test/Muon/PeriodicTableWidget_test.py
@@ -2,16 +2,11 @@ from __future__ import absolute_import, print_function
 
 import unittest
 
-from Muon.GUI.ElementalAnalysis.PeriodicTable.periodic_table_view import PeriodicTableView
-from Muon.GUI.ElementalAnalysis.PeriodicTable.periodic_table_presenter import PeriodicTablePresenter
 from Muon.GUI.ElementalAnalysis.PeriodicTable.periodic_table_widget import PeriodicTable
-from Muon.GUI.Common import mock_widget
-
-from PyQt4 import QtGui
+from Muon.GUI.ElementalAnalysis.PeriodicTable.periodic_table import PeriodicTable as silxPT
 
-from silx.gui.widgets import PeriodicTable as silxPT
+from Muon.GUI.Common import mock_widget
 
-from silx.gui.widgets.PeriodicTable import ColoredPeriodicTableItem
 
 try:
     from unittest import mock
@@ -32,12 +27,11 @@ class PeriodicTableWidgetTest(unittest.TestCase):
         self._qapp = mock_widget.mockQapp()
         self.widget = PeriodicTable()
         self.view = self.widget.presenter.view
-        self.mock_elem = ColoredPeriodicTableItem("T", 0, "", 1, "Test", 0)
-        self.mock_symbol = "T"
+        self.mock_elem = mock.Mock()
 
         self.view.ptable = mock.create_autospec(silxPT)
         self.view.ptable.getSelection = mock.Mock(
-            return_value=self.mock_symbol)
+            return_value=self.mock_elem)
         self.view.ptable.setSelection = mock.Mock()
         self.view.ptable.isElementSelected = mock.Mock(return_value=True)
         self.view.ptable.setElementSelected = mock.Mock()
@@ -50,42 +44,41 @@ class PeriodicTableWidgetTest(unittest.TestCase):
         if unregister and unreg_event is not None:
             unreg_event(handler.handler)
             func(args)
-        return handler.call_count
+        return handler.call_count == 1
 
     def test_table_clicked(self):
         assert self.call_event_once(self.widget.register_table_clicked,
-                                    self.view.table_clicked, self.mock_elem) == 1
+                                    self.view.table_clicked, self.mock_elem)
 
     def test_unregister_table_clicked(self):
         assert self.call_event_once(self.widget.register_table_clicked,
                                     self.view.table_clicked,
                                     self.mock_elem,
                                     unregister=True,
-                                    unreg_event=self.widget.unregister_table_clicked) == 1
+                                    unreg_event=self.widget.unregister_table_clicked)
 
     def test_register_table_changed(self):
         assert self.call_event_once(self.widget.register_table_changed,
-                                    self.view.table_changed, [self.mock_symbol]) == 1
+                                    self.view.table_changed, self.mock_elem)
 
     def test_unregister_table_changed(self):
         assert self.call_event_once(self.widget.register_table_changed,
                                     self.view.table_changed,
-                                    [self.mock_elem],
+                                    self.mock_elem,
                                     unregister=True,
-                                    unreg_event=self.widget.unregister_table_changed) == 1
+                                    unreg_event=self.widget.unregister_table_changed)
 
     def test_selection(self):
-        assert self.widget.selection == self.mock_symbol
+        assert self.widget.selection == self.mock_elem
 
     def test_is_selected(self):
-        assert self.widget.is_selected(self.mock_symbol)
+        assert self.widget.is_selected(self.mock_elem)
 
     def test_select_element(self):
-        self.widget.select_element(self.mock_symbol, deselect=False)
+        self.widget.select_element(self.mock_elem, deselect=False)
 
     def test_add_elements(self):
-        el = [self.mock_symbol] * 3
-        self.widget.add_elements(*el)
+        self.widget.add_elements(self.mock_elem)
 
 
 if __name__ == "__main__":