Repository: piskvorky/gensim

Issue:
Poincare visualization breaks with plotly 3.0.0    
#### Description

poincare_2d_visualization - receives the following error - 
ValueError: 
    Invalid value of type 'builtins.str' received for the 'textposition' property of scatter
        Received value: 'bottom'

#### Steps/Code/Corpus to Reproduce
Example:
```
from gensim.viz.poincare import poincare_2d_visualization
import plotly


vis = poincare_2d_visualization(model, tuples, 'Poincare Plot')
```

#### Versions
Please run the following snippet and paste the output below.
Darwin-17.2.0-x86_64-i386-64bit
Python 3.6.5 |Anaconda, Inc.| (default, Apr 26 2018, 08:42:37) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
NumPy 1.14.3
SciPy 1.1.0
gensim 3.5.0
FAST_VERSION 1
Plotly 3.0.0


Discussion:
Thanks for reporting @brettbj -- is this a bug in Plotly or in Gensim? Can you fix it?

Ideally in a way that remains compatible: works both in plotly < 3.0.0 and plotly >= 3.0.0 (in case they just renamed or re-ordered some parameters). Cheers.
Hi @brettbj,

thanks for the report, I just add full example for reproducing this issue (for jupyter-notebook)
```python
from gensim.viz.poincare import poincare_2d_visualization
from gensim.models.poincare import PoincareModel, PoincareRelations
from gensim.test.utils import datapath
from plotly.offline import init_notebook_mode, iplot

init_notebook_mode()

data = PoincareRelations(datapath('poincare_hypernyms.tsv'))
model = PoincareModel(data, negative=2, size=2)
model.train(epochs=50)

iplot(poincare_2d_visualization(model, data, 'Poincare Plot'))
```
it works for `<3.0.0`, but for more fresh version you'll see trace like
```python
ValueError                                Traceback (most recent call last)
<ipython-input-1-3a9ba43f617d> in <module>()
     10 model.train(epochs=50)
     11 
---> 12 iplot(poincare_2d_visualization(model, data, 'Poincare Plot'))

/home/ivan/.virtualenvs/math/local/lib/python2.7/site-packages/gensim/viz/poincare.pyc in poincare_2d_visualization(model, tree, figure_title, num_nodes, show_node_labels)
     60         marker=dict(color='rgb(30, 100, 200)'),
     61         text=node_labels,
---> 62         textposition='bottom'
     63     )
     64 

/home/ivan/.virtualenvs/math/local/lib/python2.7/site-packages/plotly/graph_objs/_scatter.pyc in __init__(self, arg, cliponaxis, connectgaps, customdata, customdatasrc, dx, dy, error_x, error_y, fill, fillcolor, hoverinfo, hoverinfosrc, hoverlabel, hoveron, hovertext, hovertextsrc, ids, idssrc, legendgroup, line, marker, mode, name, opacity, r, rsrc, selected, selectedpoints, showlegend, stream, t, text, textfont, textposition, textpositionsrc, textsrc, tsrc, uid, unselected, visible, x, x0, xaxis, xcalendar, xsrc, y, y0, yaxis, ycalendar, ysrc, **kwargs)
   2107         self.textfont = textfont if textfont is not None else _v
   2108         _v = arg.pop('textposition', None)
-> 2109         self.textposition = textposition if textposition is not None else _v
   2110         _v = arg.pop('textpositionsrc', None)
   2111         self.textpositionsrc = textpositionsrc if textpositionsrc is not None else _v

/home/ivan/.virtualenvs/math/local/lib/python2.7/site-packages/plotly/basedatatypes.pyc in __setattr__(self, prop, value)
   2691                 prop in self._validators):
   2692             # Let known properties and private properties through
-> 2693             super(BasePlotlyType, self).__setattr__(prop, value)
   2694         else:
   2695             # Raise error on unknown public properties

/home/ivan/.virtualenvs/math/local/lib/python2.7/site-packages/plotly/graph_objs/_scatter.pyc in textposition(self, val)
   1147     @textposition.setter
   1148     def textposition(self, val):
-> 1149         self['textposition'] = val
   1150 
   1151     # textpositionsrc

/home/ivan/.virtualenvs/math/local/lib/python2.7/site-packages/plotly/basedatatypes.pyc in __setitem__(self, prop, value)
   2663             # ### Handle simple property ###
   2664             else:
-> 2665                 self._set_prop(prop, value)
   2666 
   2667         # Handle non-scalar case

/home/ivan/.virtualenvs/math/local/lib/python2.7/site-packages/plotly/basedatatypes.pyc in _set_prop(self, prop, val)
   2893         # ------------
   2894         validator = self._validators.get(prop)
-> 2895         val = validator.validate_coerce(val)
   2896 
   2897         # val is None

/home/ivan/.virtualenvs/math/local/lib/python2.7/site-packages/_plotly_utils/basevalidators.pyc in validate_coerce(self, v)
    486             v = self.perform_replacemenet(v)
    487             if not self.in_values(v):
--> 488                 self.raise_invalid_val(v)
    489         return v
    490 

/home/ivan/.virtualenvs/math/local/lib/python2.7/site-packages/_plotly_utils/basevalidators.pyc in raise_invalid_val(self, v)
    214             typ=type_str(v),
    215             v=repr(v),
--> 216             valid_clr_desc=self.description()))
    217 
    218     def raise_invalid_elements(self, invalid_els):

ValueError: 
    Invalid value of type '__builtin__.str' received for the 'textposition' property of scatter
        Received value: 'bottom'

    The 'textposition' property is an enumeration that may be specified as:
      - One of the following enumeration values:
            ['top left', 'top center', 'top right', 'middle left',
            'middle center', 'middle right', 'bottom left', 'bottom
            center', 'bottom right']
      - A tuple, list, or one-dimensional numpy array of the above
```

**UPD**: after resolving this issue, happens 2 more problems (with `>=3.0.0`)
- `mode="line"`
- `hoverinfo=False`

need to fix it too

Resolving patch:
diff --git a/gensim/viz/poincare.py b/gensim/viz/poincare.py
--- a/gensim/viz/poincare.py
+++ b/gensim/viz/poincare.py
@@ -59,7 +59,7 @@ def poincare_2d_visualization(model, tree, figure_title, num_nodes=50, show_node
         mode='markers',
         marker=dict(color='rgb(30, 100, 200)'),
         text=node_labels,
-        textposition='bottom'
+        textposition='bottom center'
     )
 
     nodes_x, nodes_y, node_labels = [], [], []
@@ -73,7 +73,7 @@ def poincare_2d_visualization(model, tree, figure_title, num_nodes=50, show_node
         mode='markers+text',
         marker=dict(color='rgb(200, 100, 200)'),
         text=node_labels,
-        textposition='bottom'
+        textposition='bottom center'
     )
 
     node_out_degrees = Counter(hypernym_pair[1] for hypernym_pair in tree)
@@ -92,7 +92,7 @@ def poincare_2d_visualization(model, tree, figure_title, num_nodes=50, show_node
         edges_x += [vector_u[0], vector_v[0], None]
         edges_y += [vector_u[1], vector_v[1], None]
     edges = go.Scatter(
-        x=edges_x, y=edges_y, mode="line", hoverinfo=False,
+        x=edges_x, y=edges_y, mode="lines", hoverinfo='none',
         line=dict(color='rgb(50,50,50)', width=1))
 
     layout = go.Layout(


Test patch: