Hello community,

here is the log from the commit of package python-plotly for openSUSE:Factory 
checked in at 2017-11-27 22:18:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-plotly (Old)
 and      /work/SRC/openSUSE:Factory/.python-plotly.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-plotly"

Mon Nov 27 22:18:35 2017 rev:5 rq:545904 version:2.2.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-plotly/python-plotly.changes      
2017-10-31 15:43:50.290126098 +0100
+++ /work/SRC/openSUSE:Factory/.python-plotly.new/python-plotly.changes 
2017-11-27 22:18:38.306139699 +0100
@@ -1,0 +2,8 @@
+Sun Nov 26 21:26:06 UTC 2017 - [email protected]
+
+- update to version 2.2.2:
+  * bullet chart figure factory. Call
+    help(plotly.figure_factory.create_bullet) for examples and how to
+    get started making bullet charts with the API.
+
+-------------------------------------------------------------------

Old:
----
  plotly-2.2.1.tar.gz

New:
----
  plotly-2.2.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-plotly.spec ++++++
--- /var/tmp/diff_new_pack.RxBb5F/_old  2017-11-27 22:18:38.938116761 +0100
+++ /var/tmp/diff_new_pack.RxBb5F/_new  2017-11-27 22:18:38.938116761 +0100
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-plotly
-Version:        2.2.1
+Version:        2.2.2
 Release:        0
 Summary:        Library for collaborative, interactive, publication-quality 
graphs
 License:        MIT

++++++ plotly-2.2.1.tar.gz -> plotly-2.2.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/plotly-2.2.1/PKG-INFO new/plotly-2.2.2/PKG-INFO
--- old/plotly-2.2.1/PKG-INFO   2017-10-27 01:55:26.000000000 +0200
+++ new/plotly-2.2.2/PKG-INFO   2017-11-24 00:46:09.000000000 +0100
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: plotly
-Version: 2.2.1
+Version: 2.2.2
 Summary: Python plotting library for collaborative, interactive, 
publication-quality graphs.
 Home-page: https://plot.ly/python/
 Author: Chris P
 Author-email: [email protected]
 License: MIT
+Description-Content-Type: UNKNOWN
 Description: =======
         plotly:
         =======
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/plotly-2.2.1/plotly/colors.py 
new/plotly-2.2.2/plotly/colors.py
--- old/plotly-2.2.1/plotly/colors.py   2017-07-26 14:04:02.000000000 +0200
+++ new/plotly-2.2.2/plotly/colors.py   2017-11-24 00:45:47.000000000 +0100
@@ -442,21 +442,37 @@
         return colorscale
 
 
-def find_intermediate_color(lowcolor, highcolor, intermed):
+def find_intermediate_color(lowcolor, highcolor, intermed, colortype='tuple'):
     """
     Returns the color at a given distance between two colors
 
     This function takes two color tuples, where each element is between 0
     and 1, along with a value 0 < intermed < 1 and returns a color that is
-    intermed-percent from lowcolor to highcolor
-    """
+    intermed-percent from lowcolor to highcolor. If colortype is set to 'rgb',
+    the function will automatically convert the rgb type to a tuple, find the
+    intermediate color and return it as an rgb color.
+    """
+    if colortype == 'rgb':
+        # convert to tuple color, eg. (1, 0.45, 0.7)
+        lowcolor = unlabel_rgb(lowcolor)
+        highcolor = unlabel_rgb(highcolor)
+
     diff_0 = float(highcolor[0] - lowcolor[0])
     diff_1 = float(highcolor[1] - lowcolor[1])
     diff_2 = float(highcolor[2] - lowcolor[2])
 
-    return (lowcolor[0] + intermed * diff_0,
-            lowcolor[1] + intermed * diff_1,
-            lowcolor[2] + intermed * diff_2)
+    inter_med_tuple = (
+        lowcolor[0] + intermed * diff_0,
+        lowcolor[1] + intermed * diff_1,
+        lowcolor[2] + intermed * diff_2
+    )
+
+    if colortype == 'rgb':
+        # back to an rgb string, e.g. rgb(30, 20, 10)
+        inter_med_rgb = label_rgb(inter_med_tuple)
+        return inter_med_rgb
+
+    return inter_med_tuple
 
 
 def unconvert_from_RGB_255(colors):
@@ -498,29 +514,39 @@
     return (rgb_components[0], rgb_components[1], rgb_components[2])
 
 
-def n_colors(lowcolor, highcolor, n_colors):
+def n_colors(lowcolor, highcolor, n_colors, colortype='tuple'):
     """
     Splits a low and high color into a list of n_colors colors in it
 
     Accepts two color tuples and returns a list of n_colors colors
     which form the intermediate colors between lowcolor and highcolor
-    from linearly interpolating through RGB space
+    from linearly interpolating through RGB space. If colortype is 'rgb'
+    the function will return a list of colors in the same form.
     """
+    if colortype == 'rgb':
+        # convert to tuple
+        lowcolor = unlabel_rgb(lowcolor)
+        highcolor = unlabel_rgb(highcolor)
+
     diff_0 = float(highcolor[0] - lowcolor[0])
     incr_0 = diff_0/(n_colors - 1)
     diff_1 = float(highcolor[1] - lowcolor[1])
     incr_1 = diff_1/(n_colors - 1)
     diff_2 = float(highcolor[2] - lowcolor[2])
     incr_2 = diff_2/(n_colors - 1)
-    color_tuples = []
+    list_of_colors = []
 
     for index in range(n_colors):
         new_tuple = (lowcolor[0] + (index * incr_0),
                      lowcolor[1] + (index * incr_1),
                      lowcolor[2] + (index * incr_2))
-        color_tuples.append(new_tuple)
+        list_of_colors.append(new_tuple)
+
+    if colortype == 'rgb':
+        # back to an rgb string
+        list_of_colors = color_parser(list_of_colors, label_rgb)
 
-    return color_tuples
+    return list_of_colors
 
 
 def label_rgb(colors):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/plotly-2.2.1/plotly/figure_factory/__init__.py 
new/plotly-2.2.2/plotly/figure_factory/__init__.py
--- old/plotly-2.2.1/plotly/figure_factory/__init__.py  2017-07-26 
14:04:02.000000000 +0200
+++ new/plotly-2.2.2/plotly/figure_factory/__init__.py  2017-11-24 
00:45:47.000000000 +0100
@@ -5,6 +5,7 @@
 
 from plotly.figure_factory._2d_density import create_2d_density
 from plotly.figure_factory._annotated_heatmap import create_annotated_heatmap
+from plotly.figure_factory._bullet import create_bullet
 from plotly.figure_factory._candlestick import create_candlestick
 from plotly.figure_factory._dendrogram import create_dendrogram
 from plotly.figure_factory._distplot import create_distplot
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/plotly-2.2.1/plotly/figure_factory/_bullet.py 
new/plotly-2.2.2/plotly/figure_factory/_bullet.py
--- old/plotly-2.2.1/plotly/figure_factory/_bullet.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/plotly-2.2.2/plotly/figure_factory/_bullet.py   2017-11-24 
00:45:47.000000000 +0100
@@ -0,0 +1,345 @@
+from __future__ import absolute_import
+
+import collections
+import math
+
+from plotly import colors, exceptions, optional_imports
+from plotly.figure_factory import utils
+
+import plotly
+import plotly.graph_objs as go
+
+pd = optional_imports.get_module('pandas')
+
+
+def is_sequence(obj):
+    return (isinstance(obj, collections.Sequence) and
+            not isinstance(obj, str))
+
+
+def _bullet(df, markers, measures, ranges, subtitles, titles, orientation,
+            range_colors, measure_colors, horizontal_spacing,
+            vertical_spacing, scatter_options, layout_options):
+
+    num_of_lanes = len(df)
+    num_of_rows = num_of_lanes if orientation == 'h' else 1
+    num_of_cols = 1 if orientation == 'h' else num_of_lanes
+    if not horizontal_spacing:
+        horizontal_spacing = 1./num_of_lanes
+    if not vertical_spacing:
+        vertical_spacing = 1./num_of_lanes
+    fig = plotly.tools.make_subplots(
+        num_of_rows, num_of_cols, print_grid=False,
+        horizontal_spacing=horizontal_spacing,
+        vertical_spacing=vertical_spacing
+    )
+
+    # layout
+    fig['layout'].update(
+        dict(shapes=[]),
+        title='Bullet Chart',
+        height=600,
+        width=1000,
+        showlegend=False,
+        barmode='stack',
+        annotations=[],
+        margin=dict(l=120 if orientation == 'h' else 80),
+    )
+
+    # update layout
+    fig['layout'].update(layout_options)
+
+    if orientation == 'h':
+        width_axis = 'yaxis'
+        length_axis = 'xaxis'
+    else:
+        width_axis = 'xaxis'
+        length_axis = 'yaxis'
+
+    for key in fig['layout'].keys():
+        if 'axis' in key:
+            fig['layout'][key]['showgrid'] = False
+            fig['layout'][key]['zeroline'] = False
+        if length_axis in key:
+            fig['layout'][key]['tickwidth'] = 1
+        if width_axis in key:
+            fig['layout'][key]['showticklabels'] = False
+            fig['layout'][key]['range'] = [0, 1]
+
+    # narrow domain if 1 bar
+    if num_of_lanes <= 1:
+        fig['layout'][width_axis + '1']['domain'] = [0.4, 0.6]
+
+    if not range_colors:
+        range_colors = ['rgb(200, 200, 200)', 'rgb(245, 245, 245)']
+    if not measure_colors:
+        measure_colors = ['rgb(31, 119, 180)', 'rgb(176, 196, 221)']
+
+    for row in range(num_of_lanes):
+        # ranges bars
+        for idx in range(len(df.iloc[row]['ranges'])):
+            inter_colors = colors.n_colors(
+                range_colors[0], range_colors[1],
+                len(df.iloc[row]['ranges']), 'rgb'
+            )
+            x = ([sorted(df.iloc[row]['ranges'])[-1 - idx]] if
+                 orientation == 'h' else [0])
+            y = ([0] if orientation == 'h' else
+                 [sorted(df.iloc[row]['ranges'])[-1 - idx]])
+            bar = go.Bar(
+                x=x,
+                y=y,
+                marker=dict(
+                    color=inter_colors[-1 - idx]
+                ),
+                name='ranges',
+                hoverinfo='x' if orientation == 'h' else 'y',
+                orientation=orientation,
+                width=2,
+                base=0,
+                xaxis='x{}'.format(row + 1),
+                yaxis='y{}'.format(row + 1)
+            )
+            fig['data'].append(bar)
+
+        # measures bars
+        for idx in range(len(df.iloc[row]['measures'])):
+            inter_colors = colors.n_colors(
+                measure_colors[0], measure_colors[1],
+                len(df.iloc[row]['measures']), 'rgb'
+            )
+            x = ([sorted(df.iloc[row]['measures'])[-1 - idx]] if
+                 orientation == 'h' else [0.5])
+            y = ([0.5] if orientation == 'h'
+                 else [sorted(df.iloc[row]['measures'])[-1 - idx]])
+            bar = go.Bar(
+                x=x,
+                y=y,
+                marker=dict(
+                    color=inter_colors[-1 - idx]
+                ),
+                name='measures',
+                hoverinfo='x' if orientation == 'h' else 'y',
+                orientation=orientation,
+                width=0.4,
+                base=0,
+                xaxis='x{}'.format(row + 1),
+                yaxis='y{}'.format(row + 1)
+            )
+            fig['data'].append(bar)
+
+        # markers
+        x = df.iloc[row]['markers'] if orientation == 'h' else [0.5]
+        y = [0.5] if orientation == 'h' else df.iloc[row]['markers']
+        markers = go.Scatter(
+            x=x,
+            y=y,
+            name='markers',
+            hoverinfo='x' if orientation == 'h' else 'y',
+            xaxis='x{}'.format(row + 1),
+            yaxis='y{}'.format(row + 1),
+            **scatter_options
+        )
+
+        fig['data'].append(markers)
+
+        # titles and subtitles
+        title = df.iloc[row]['titles']
+        if 'subtitles' in df:
+            subtitle = '<br>{}'.format(df.iloc[row]['subtitles'])
+        else:
+            subtitle = ''
+        label = '<b>{}</b>'.format(title) + subtitle
+        annot = utils.annotation_dict_for_label(
+            label,
+            (num_of_lanes - row if orientation == 'h' else row + 1),
+            num_of_lanes,
+            vertical_spacing if orientation == 'h' else horizontal_spacing,
+            'row' if orientation == 'h' else 'col',
+            True if orientation == 'h' else False,
+            False
+        )
+        fig['layout']['annotations'].append(annot)
+
+    return fig
+
+
+def create_bullet(data, markers=None, measures=None, ranges=None,
+                  subtitles=None, titles=None, orientation='h',
+                  range_colors=('rgb(200, 200, 200)', 'rgb(245, 245, 245)'),
+                  measure_colors=('rgb(31, 119, 180)', 'rgb(176, 196, 221)'),
+                  horizontal_spacing=None, vertical_spacing=None,
+                  scatter_options={}, **layout_options):
+    """
+    Returns figure for bullet chart.
+
+    :param (pd.DataFrame | list | tuple) data: either a list/tuple of
+        dictionaries or a pandas DataFrame.
+    :param (str) markers: the column name or dictionary key for the markers in
+        each subplot.
+    :param (str) measures: the column name or dictionary key for the measure
+        bars in each subplot. This bar usually represents the quantitative
+        measure of performance, usually a list of two values [a, b] and are
+        the blue bars in the foreground of each subplot by default.
+    :param (str) ranges: the column name or dictionary key for the qualitative
+        ranges of performance, usually a 3-item list [bad, okay, good]. They
+        correspond to the grey bars in the background of each chart.
+    :param (str) subtitles: the column name or dictionary key for the subtitle
+        of each subplot chart. The subplots are displayed right underneath
+        each title.
+    :param (str) titles: the column name or dictionary key for the main label
+        of each subplot chart.
+    :param (bool) orientation: if 'h', the bars are placed horizontally as
+        rows. If 'v' the bars are placed vertically in the chart.
+    :param (list) range_colors: a tuple of two colors between which all
+        the rectangles for the range are drawn. These rectangles are meant to
+        be qualitative indicators against which the marker and measure bars
+        are compared.
+        Default=('rgb(200, 200, 200)', 'rgb(245, 245, 245)')
+    :param (list) measure_colors: a tuple of two colors which is used to color
+        the thin quantitative bars in the bullet chart.
+        Default=('rgb(31, 119, 180)', 'rgb(176, 196, 221)')
+    :param (float) horizontal_spacing: see the 'horizontal_spacing' param in
+        plotly.tools.make_subplots. Ranges between 0 and 1.
+    :param (float) vertical_spacing: see the 'vertical_spacing' param in
+        plotly.tools.make_subplots. Ranges between 0 and 1.
+    :param (dict) scatter_options: describes attributes for the scatter trace
+        in each subplot such as name and marker size. Call
+        help(plotly.graph_objs.Scatter) for more information on valid params.
+    :param layout_options: describes attributes for the layout of the figure
+        such as title, height and width. Call help(plotly.graph_objs.Layout)
+        for more information on valid params.
+
+    Example 1: Use a Dictionary
+    ```
+    import plotly
+    import plotly.plotly as py
+    import plotly.figure_factory as ff
+
+    data = [
+      {"label": "Revenue", "sublabel": "US$, in thousands",
+       "range": [150, 225, 300], "performance": [220,270], "point": [250]},
+      {"label": "Profit", "sublabel": "%", "range": [20, 25, 30],
+       "performance": [21, 23], "point": [26]},
+      {"label": "Order Size", "sublabel":"US$, average","range": [350, 500, 
600],
+       "performance": [100,320],"point": [550]},
+      {"label": "New Customers", "sublabel": "count", "range": [1400, 2000, 
2500],
+       "performance": [1000, 1650],"point": [2100]},
+      {"label": "Satisfaction", "sublabel": "out of 5","range": [3.5, 4.25, 5],
+       "performance": [3.2, 4.7], "point": [4.4]}
+    ]
+
+    fig = ff.create_bullet(
+        data, titles='label', subtitles='sublabel', markers='point',
+        measures='performance', ranges='range', orientation='h',
+        title='my simple bullet chart'
+    )
+    py.iplot(fig)
+    ```
+
+    Example 2: Use a DataFrame with Custom Colors
+    ```
+    import plotly.plotly as py
+    import plotly.figure_factory as ff
+
+    import pandas as pd
+
+    data = 
pd.read_json('https://cdn.rawgit.com/plotly/datasets/master/BulletData.json')
+
+    fig = ff.create_bullet(
+        data, titles='title', markers='markers', measures='measures',
+        orientation='v', measure_colors=['rgb(14, 52, 75)', 'rgb(31, 141, 
127)'],
+        scatter_options={'marker': {'symbol': 'circle'}}, width=700
+
+    )
+    py.iplot(fig)
+    ```
+    """
+    # validate df
+    if not pd:
+        raise exceptions.ImportError(
+            "'pandas' must be installed for this figure factory."
+        )
+
+    if is_sequence(data):
+        if not all(isinstance(item, dict) for item in data):
+            raise exceptions.PlotlyError(
+                'Every entry of the data argument list, tuple, etc must '
+                'be a dictionary.'
+            )
+
+    elif not isinstance(data, pd.DataFrame):
+        raise exceptions.PlotlyError(
+            'You must input a pandas DataFrame, or a list of dictionaries.'
+        )
+
+    # make DataFrame from data with correct column headers
+    col_names = ['titles', 'subtitle', 'markers', 'measures', 'ranges']
+    if is_sequence(data):
+        df = pd.DataFrame(
+            [
+                [d[titles] for d in data] if titles else [''] * len(data),
+                [d[subtitles] for d in data] if subtitles else [''] * 
len(data),
+                [d[markers] for d in data] if markers else [[]] * len(data),
+                [d[measures] for d in data] if measures else [[]] * len(data),
+                [d[ranges] for d in data] if ranges else [[]] * len(data),
+            ],
+            index=col_names
+        )
+    elif isinstance(data, pd.DataFrame):
+        df = pd.DataFrame(
+            [
+                data[titles].tolist() if titles else [''] * len(data),
+                data[subtitles].tolist() if subtitles else [''] * len(data),
+                data[markers].tolist() if markers else [[]] * len(data),
+                data[measures].tolist() if measures else [[]] * len(data),
+                data[ranges].tolist() if ranges else [[]] * len(data),
+            ],
+            index=col_names
+        )
+    df = pd.DataFrame.transpose(df)
+
+    # make sure ranges, measures, 'markers' are not NAN or NONE
+    for needed_key in ['ranges', 'measures', 'markers']:
+        for idx, r in enumerate(df[needed_key]):
+            try:
+                r_is_nan = math.isnan(r)
+                if r_is_nan or r is None:
+                    df[needed_key][idx] = []
+            except TypeError:
+                pass
+
+    # validate custom colors
+    for colors_list in [range_colors, measure_colors]:
+        if colors_list:
+            if len(colors_list) != 2:
+                raise exceptions.PlotlyError(
+                    "Both 'range_colors' or 'measure_colors' must be a list "
+                    "of two valid colors."
+                )
+            colors.validate_colors(colors_list)
+            colors_list = colors.convert_colors_to_same_type(colors_list,
+                                                             'rgb')[0]
+
+    # default scatter options
+    default_scatter = {
+        'marker': {'size': 12,
+                   'symbol': 'diamond-tall',
+                   'color': 'rgb(0, 0, 0)'}
+    }
+
+    if scatter_options == {}:
+        scatter_options.update(default_scatter)
+    else:
+        # add default options to scatter_options if they are not present
+        for k in default_scatter['marker']:
+            if k not in scatter_options['marker']:
+                scatter_options['marker'][k] = default_scatter['marker'][k]
+
+    fig = _bullet(
+        df, markers, measures, ranges, subtitles, titles, orientation,
+        range_colors, measure_colors, horizontal_spacing, vertical_spacing,
+        scatter_options, layout_options,
+    )
+
+    return fig
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/plotly-2.2.1/plotly/figure_factory/_facet_grid.py 
new/plotly-2.2.2/plotly/figure_factory/_facet_grid.py
--- old/plotly-2.2.1/plotly/figure_factory/_facet_grid.py       2017-07-26 
14:04:02.000000000 +0200
+++ new/plotly-2.2.2/plotly/figure_factory/_facet_grid.py       2017-11-24 
00:45:47.000000000 +0100
@@ -778,7 +778,7 @@
     """
     if not pd:
         raise exceptions.ImportError(
-            "'pandas' must be imported for this figure_factory."
+            "'pandas' must be installed for this figure_factory."
         )
 
     if not isinstance(df, pd.DataFrame):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/plotly-2.2.1/plotly/figure_factory/utils.py 
new/plotly-2.2.2/plotly/figure_factory/utils.py
--- old/plotly-2.2.1/plotly/figure_factory/utils.py     2017-07-26 
14:04:02.000000000 +0200
+++ new/plotly-2.2.2/plotly/figure_factory/utils.py     2017-11-24 
00:45:47.000000000 +0100
@@ -488,3 +488,85 @@
         # add +inf to intervals
         intervals.append([endpts[length - 1], float('inf')])
         return intervals
+
+
+def annotation_dict_for_label(text, lane, num_of_lanes, subplot_spacing,
+                              row_col='col', flipped=True, right_side=True,
+                              text_color='#0f0f0f'):
+    """
+    Returns annotation dict for label of n labels of a 1xn or nx1 subplot.
+
+    :param (str) text: the text for a label.
+    :param (int) lane: the label number for text. From 1 to n inclusive.
+    :param (int) num_of_lanes: the number 'n' of rows or columns in subplot.
+    :param (float) subplot_spacing: the value for the horizontal_spacing and
+        vertical_spacing params in your plotly.tools.make_subplots() call.
+    :param (str) row_col: choose whether labels are placed along rows or
+        columns.
+    :param (bool) flipped: flips text by 90 degrees. Text is printed
+        horizontally if set to True and row_col='row', or if False and
+        row_col='col'.
+    :param (bool) right_side: only applicable if row_col is set to 'row'.
+    :param (str) text_color: color of the text.
+    """
+    l = (1 - (num_of_lanes - 1) * subplot_spacing) / (num_of_lanes)
+    if not flipped:
+        xanchor = 'center'
+        yanchor = 'middle'
+        if row_col == 'col':
+            x = (lane - 1) * (l + subplot_spacing) + 0.5 * l
+            y = 1.03
+            textangle = 0
+        elif row_col == 'row':
+            y = (lane - 1) * (l + subplot_spacing) + 0.5 * l
+            x = 1.03
+            textangle = 90
+    else:
+        if row_col == 'col':
+            xanchor = 'center'
+            yanchor = 'bottom'
+            x = (lane - 1) * (l + subplot_spacing) + 0.5 * l
+            y = 1.0
+            textangle = 270
+        elif row_col == 'row':
+            yanchor = 'middle'
+            y = (lane - 1) * (l + subplot_spacing) + 0.5 * l
+            if right_side:
+                x = 1.0
+                xanchor = 'left'
+            else:
+                x = -0.01
+                xanchor = 'right'
+            textangle = 0
+
+    annotation_dict = dict(
+        textangle=textangle,
+        xanchor=xanchor,
+        yanchor=yanchor,
+        x=x,
+        y=y,
+        showarrow=False,
+        xref='paper',
+        yref='paper',
+        text=text,
+        font=dict(
+            size=13,
+            color=text_color
+        )
+    )
+    return annotation_dict
+
+
+def list_of_options(iterable, conj='and', period=True):
+    """
+    Returns an English listing of objects seperated by commas ','
+
+    For example, ['foo', 'bar', 'baz'] becomes 'foo, bar and baz'
+    if the conjunction 'and' is selected.
+    """
+    if len(iterable) < 2:
+        raise exceptions.PlotlyError(
+            'Your list or tuple must contain at least 2 items.'
+        )
+    template = (len(iterable) - 2)*'{}, ' + '{} ' + conj + ' {}' + period*'.'
+    return template.format(*iterable)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/plotly-2.2.1/plotly/version.py 
new/plotly-2.2.2/plotly/version.py
--- old/plotly-2.2.1/plotly/version.py  2017-10-27 01:54:28.000000000 +0200
+++ new/plotly-2.2.2/plotly/version.py  2017-11-24 00:45:47.000000000 +0100
@@ -1 +1 @@
-__version__ = '2.2.1'
+__version__ = '2.2.2'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/plotly-2.2.1/plotly.egg-info/PKG-INFO 
new/plotly-2.2.2/plotly.egg-info/PKG-INFO
--- old/plotly-2.2.1/plotly.egg-info/PKG-INFO   2017-10-27 01:55:26.000000000 
+0200
+++ new/plotly-2.2.2/plotly.egg-info/PKG-INFO   2017-11-24 00:46:08.000000000 
+0100
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: plotly
-Version: 2.2.1
+Version: 2.2.2
 Summary: Python plotting library for collaborative, interactive, 
publication-quality graphs.
 Home-page: https://plot.ly/python/
 Author: Chris P
 Author-email: [email protected]
 License: MIT
+Description-Content-Type: UNKNOWN
 Description: =======
         plotly:
         =======
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/plotly-2.2.1/plotly.egg-info/SOURCES.txt 
new/plotly-2.2.2/plotly.egg-info/SOURCES.txt
--- old/plotly-2.2.1/plotly.egg-info/SOURCES.txt        2017-10-27 
01:55:26.000000000 +0200
+++ new/plotly-2.2.2/plotly.egg-info/SOURCES.txt        2017-11-24 
00:46:09.000000000 +0100
@@ -40,6 +40,7 @@
 plotly/figure_factory/_2d_density.py
 plotly/figure_factory/__init__.py
 plotly/figure_factory/_annotated_heatmap.py
+plotly/figure_factory/_bullet.py
 plotly/figure_factory/_candlestick.py
 plotly/figure_factory/_dendrogram.py
 plotly/figure_factory/_distplot.py


Reply via email to