diff --git a/CHANGELOG.md b/CHANGELOG.md index eaed43e1e5..d7936b001d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [2.5.0] - UNRELEASED ### Fixed - `import plotly.figure_factory` does not fail if `pandas` is not installed. See https://github.com/plotly/plotly.py/pull/958 +### Added +- New parameter `fill_percent` to the `.insert` method for the dashboards API. You can now insert a box into the dashboard layout and specify what proportion of the original container box it will occupy. Run `help(plotly.dashboard_objs.Dashboard.insert)` for more information on `fill_percent`. +### Updated +- `plotly.figure_factory.create_choropleth` has changed some of the default plotting options: + - 'offline_mode' param has been removed from call signature + - persistent selection api for the centroid points is automatically enabled. See https://plot.ly/python/reference/#scatter-selected and https://plot.ly/python/reference/#scatter-unselected for details + - FIPS values that appear on hover are 0-padded to ensure they are 5 digits + - for the county lines data `hover_info='none'` by default ## [2.4.1] - 2018-02-21 ### Fixed @@ -677,4 +685,4 @@ it does. ``` ### Fixed -- The height of the graph in `iplot` respects the figure's height in layout +- The height of the graph in `iplot` respects the figure's height in layout \ No newline at end of file diff --git a/circle.yml b/circle.yml index 0703e482f2..28413b9b88 100644 --- a/circle.yml +++ b/circle.yml @@ -12,7 +12,7 @@ machine: node: # use a pre-installed version of node so we don't need to download it. - version: 4.2.2 + version: 6.0.0 dependencies: diff --git a/plotly/dashboard_objs/dashboard_objs.py b/plotly/dashboard_objs/dashboard_objs.py index 1b3b215ed3..9b6c3c8467 100644 --- a/plotly/dashboard_objs/dashboard_objs.py +++ b/plotly/dashboard_objs/dashboard_objs.py @@ -15,10 +15,11 @@ IPython = optional_imports.get_module('IPython') -# default HTML parameters -MASTER_WIDTH = 400 -MASTER_HEIGHT = 400 -FONT_SIZE = 10 +# default parameters for HTML preview +MASTER_WIDTH = 500 +MASTER_HEIGHT = 500 +FONT_SIZE = 9 + ID_NOT_VALID_MESSAGE = ( "Your box_id must be a number in your dashboard. To view a " @@ -44,9 +45,9 @@ def _box(fileId='', shareKey=None, title=''): } return box - -def _container(box_1=None, box_2=None, size=MASTER_HEIGHT, - sizeUnit='px', direction='vertical'): +def _container(box_1=None, box_2=None, + size=50, sizeUnit='%', + direction='vertical'): if box_1 is None: box_1 = _empty_box() if box_2 is None: @@ -60,6 +61,7 @@ def _container(box_1=None, box_2=None, size=MASTER_HEIGHT, 'first': box_1, 'second': box_2 } + return container dashboard_html = (""" @@ -74,7 +76,7 @@ def _container(box_1=None, box_2=None, size=MASTER_HEIGHT, - + ') - 1 dashboard_html = (dashboard_html[:index_to_add_text] + html_text + @@ -161,43 +161,62 @@ class Dashboard(dict): `.get_box()` returns the box located in the dashboard by calling its box id as displayed via `.get_preview()`. - Example: Create a simple Dashboard object + Example 1: Create a simple Dashboard object ``` import plotly.dashboard_objs as dashboard - box_1 = { + box_a = { 'type': 'box', 'boxType': 'plot', 'fileId': 'username:some#', - 'title': 'box 1' + 'title': 'box a' } - box_2 = { + box_b = { 'type': 'box', 'boxType': 'plot', 'fileId': 'username:some#', - 'title': 'box 2' + 'title': 'box b' } - box_3 = { + box_c = { 'type': 'box', 'boxType': 'plot', 'fileId': 'username:some#', - 'title': 'box 3' + 'title': 'box c' } my_dboard = dashboard.Dashboard() - my_dboard.insert(box_1) + my_dboard.insert(box_a) # my_dboard.get_preview() - my_dboard.insert(box_2, 'above', 1) + my_dboard.insert(box_b, 'above', 1) # my_dboard.get_preview() - my_dboard.insert(box_3, 'left', 2) + my_dboard.insert(box_c, 'left', 2) # my_dboard.get_preview() my_dboard.swap(1, 2) # my_dboard.get_preview() my_dboard.remove(1) # my_dboard.get_preview() ``` + + Example 2: 4 vertical boxes of equal height + ``` + import plotly.dashboard_objs as dashboard + + box_a = { + 'type': 'box', + 'boxType': 'plot', + 'fileId': 'username:some#', + 'title': 'box a' + } + + my_dboard = dashboard.Dashboard() + my_dboard.insert(box_a) + my_dboard.insert(box_a, 'below', 1) + my_dboard.insert(box_a, 'below', 1) + my_dboard.insert(box_a, 'below', 3) + # my_dboard.get_preview() + ``` """ def __init__(self, content=None): if content is None: @@ -212,12 +231,10 @@ def __init__(self, content=None): self['version'] = content['version'] self['settings'] = content['settings'] - self._set_container_sizes() - def _compute_box_ids(self): box_ids_to_path = {} all_nodes = list(node_generator(self['layout'])) - + all_nodes.sort(key=lambda x: x[1]) for node in all_nodes: if (node[1] != () and node[0]['type'] == 'box' and node[0]['boxType'] != 'empty'): @@ -250,6 +267,7 @@ def _insert(self, box_or_container, path): def _make_all_nodes_and_paths(self): all_nodes = list(node_generator(self['layout'])) + all_nodes.sort(key=lambda x: x[1]) # remove path 'second' as it's always an empty box all_paths = [] @@ -260,30 +278,27 @@ def _make_all_nodes_and_paths(self): all_paths.remove(path_second) return all_nodes, all_paths - def _set_container_sizes(self): - if self['layout'] is None: - return - - all_nodes, all_paths = self._make_all_nodes_and_paths() - - # set dashboard_height proportional to max_path_len - max_path_len = max(len(path) for path in all_paths) - dashboard_height = 500 + 250 * max_path_len - self['layout']['size'] = dashboard_height - self['layout']['sizeUnit'] = 'px' - - for path in all_paths: - if len(path) != 0: - if self._path_to_box(path)['type'] == 'split': - self._path_to_box(path)['size'] = 50 - self._path_to_box(path)['sizeUnit'] = '%' - def _path_to_box(self, path): loc_in_dashboard = self['layout'] for first_second in path: loc_in_dashboard = loc_in_dashboard[first_second] return loc_in_dashboard + def _set_dashboard_size(self): + # set dashboard size to keep consistent with GUI + num_of_boxes = len(self._compute_box_ids()) + if num_of_boxes == 0: + pass + elif num_of_boxes == 1: + self['layout']['size'] = 800 + self['layout']['sizeUnit'] = 'px' + elif num_of_boxes == 2: + self['layout']['size'] = 1500 + self['layout']['sizeUnit'] = 'px' + else: + self['layout']['size'] = 1500 + 350 * (num_of_boxes - 2) + self['layout']['sizeUnit'] = 'px' + def get_box(self, box_id): """Returns box from box_id number.""" box_ids_to_path = self._compute_box_ids() @@ -325,8 +340,8 @@ def get_preview(self): elif self['layout'] is None: return IPython.display.HTML(dashboard_html) - x = 0 - y = 0 + top_left_x = 0 + top_left_y = 0 box_w = MASTER_WIDTH box_h = MASTER_HEIGHT html_figure = dashboard_html @@ -334,8 +349,8 @@ def get_preview(self): # used to store info about box dimensions path_to_box_specs = {} first_box_specs = { - 'top_left_x': x, - 'top_left_y': y, + 'top_left_x': top_left_x, + 'top_left_y': top_left_y, 'box_w': box_w, 'box_h': box_h } @@ -351,57 +366,64 @@ def get_preview(self): current_box_specs = path_to_box_specs[path] if self._path_to_box(path)['type'] == 'split': - html_figure = _draw_line_through_box( - html_figure, - current_box_specs['top_left_x'], - current_box_specs['top_left_y'], - current_box_specs['box_w'], - current_box_specs['box_h'], - direction=self._path_to_box(path)['direction'] - ) + fill_percent = self._path_to_box(path)['size'] + direction = self._path_to_box(path)['direction'] + is_horizontal = (direction == 'horizontal') - # determine the specs for resulting two boxes from split - is_horizontal = ( - self._path_to_box(path)['direction'] == 'horizontal' - ) - x = current_box_specs['top_left_x'] - y = current_box_specs['top_left_y'] + top_left_x = current_box_specs['top_left_x'] + top_left_y = current_box_specs['top_left_y'] box_w = current_box_specs['box_w'] box_h = current_box_specs['box_h'] + html_figure = _draw_line_through_box( + html_figure, top_left_x, top_left_y, box_w, box_h, + is_horizontal=is_horizontal, direction=direction, + fill_percent=fill_percent + ) + + # determine the specs for resulting two box split if is_horizontal: - new_box_w = box_w / 2 + new_top_left_x = top_left_x + new_top_left_y = top_left_y + new_box_w = box_w * (fill_percent / 100.) new_box_h = box_h - new_top_left_x = x + box_w / 2 - new_top_left_y = y + new_top_left_x_2 = top_left_x + new_box_w + new_top_left_y_2 = top_left_y + new_box_w_2 = box_w * ((100 - fill_percent) / 100.) + new_box_h_2 = box_h else: + new_top_left_x = top_left_x + new_top_left_y = top_left_y new_box_w = box_w - new_box_h = box_h / 2 - new_top_left_x = x - new_top_left_y = y + box_h / 2 + new_box_h = box_h * (fill_percent / 100.) - box_1_specs = { - 'top_left_x': x, - 'top_left_y': y, + new_top_left_x_2 = top_left_x + new_top_left_y_2 = (top_left_y + + box_h * (fill_percent / 100.)) + new_box_w_2 = box_w + new_box_h_2 = box_h * ((100 - fill_percent) / 100.) + + first_box_specs = { + 'top_left_x': top_left_x, + 'top_left_y': top_left_y, 'box_w': new_box_w, 'box_h': new_box_h } - box_2_specs = { - 'top_left_x': new_top_left_x, - 'top_left_y': new_top_left_y, - 'box_w': new_box_w, - 'box_h': new_box_h + second_box_specs = { + 'top_left_x': new_top_left_x_2, + 'top_left_y': new_top_left_y_2, + 'box_w': new_box_w_2, + 'box_h': new_box_h_2 } - path_to_box_specs[path + ('first',)] = box_1_specs - path_to_box_specs[path + ('second',)] = box_2_specs + path_to_box_specs[path + ('first',)] = first_box_specs + path_to_box_specs[path + ('second',)] = second_box_specs elif self._path_to_box(path)['type'] == 'box': for box_id in box_ids_to_path: if box_ids_to_path[box_id] == path: number = box_id - html_figure = _add_html_text( html_figure, number, path_to_box_specs[path]['top_left_x'], @@ -413,7 +435,7 @@ def get_preview(self): # display HTML representation return IPython.display.HTML(html_figure) - def insert(self, box, side='above', box_id=None): + def insert(self, box, side='above', box_id=None, fill_percent=50): """ Insert a box into your dashboard layout. @@ -421,26 +443,35 @@ def insert(self, box, side='above', box_id=None): :param (str) side: specifies where your new box is going to be placed relative to the given 'box_id'. Valid values are 'above', 'below', 'left', and 'right'. - :param (int) box_id: the box id which is used as the reference box for - the insertion of the box. - + :param (int) box_id: the box id which is used as a reference for the + insertion of the new box. Box ids are memoryless numbers that are + generated on-the-fly and assigned to boxes in the layout each time + .get_preview() is run. + :param (float) fill_percent: specifies the percentage of the container + box from the given 'side' that the new box occupies. For example + if you apply the method\n + .insert(box=new_box, box_id=2, side='left', fill_percent=20)\n + to a dashboard object, a new box is inserted 20% from the left + side of the box with id #2. Run .get_preview() to see the box ids + assigned to each box in the dashboard layout. + Default = 50 Example: ``` import plotly.dashboard_objs as dashboard - box_1 = { + box_a = { 'type': 'box', 'boxType': 'plot', 'fileId': 'username:some#', - 'title': 'box 1' + 'title': 'box a' } my_dboard = dashboard.Dashboard() - my_dboard.insert(box_1) - my_dboard.insert(box_1, 'left', 1) - my_dboard.insert(box_1, 'below', 2) - my_dboard.insert(box_1, 'right', 3) - my_dboard.insert(box_1, 'above', 4) + my_dboard.insert(box_a) + my_dboard.insert(box_a, 'left', 1) + my_dboard.insert(box_a, 'below', 2) + my_dboard.insert(box_a, 'right', 3) + my_dboard.insert(box_a, 'above', 4, fill_percent=20) my_dboard.get_preview() ``` @@ -449,7 +480,9 @@ def insert(self, box, side='above', box_id=None): # doesn't need box_id or side specified for first box if self['layout'] is None: - self['layout'] = _container(box, _empty_box()) + self['layout'] = _container( + box, _empty_box(), size=MASTER_HEIGHT, sizeUnit='px' + ) else: if box_id is None: raise exceptions.PlotlyError( @@ -458,28 +491,38 @@ def insert(self, box, side='above', box_id=None): ) if box_id not in box_ids_to_path: raise exceptions.PlotlyError(ID_NOT_VALID_MESSAGE) + + if fill_percent < 0 or fill_percent > 100: + raise exceptions.PlotlyError( + 'fill_percent must be a number between 0 and 100 ' + 'inclusive' + ) if side == 'above': old_box = self.get_box(box_id) self._insert( - _container(box, old_box, direction='vertical'), + _container(box, old_box, direction='vertical', + size=fill_percent), box_ids_to_path[box_id] ) elif side == 'below': old_box = self.get_box(box_id) self._insert( - _container(old_box, box, direction='vertical'), + _container(old_box, box, direction='vertical', + size=100 - fill_percent), box_ids_to_path[box_id] ) elif side == 'left': old_box = self.get_box(box_id) self._insert( - _container(box, old_box, direction='horizontal'), + _container(box, old_box, direction='horizontal', + size=fill_percent), box_ids_to_path[box_id] ) elif side == 'right': old_box = self.get_box(box_id) self._insert( - _container(old_box, box, direction='horizontal'), + _container(old_box, box, direction='horizontal', + size =100 - fill_percent), box_ids_to_path[box_id] ) else: @@ -489,7 +532,7 @@ def insert(self, box, side='above', box_id=None): "'above', 'below', 'left', and 'right'." ) - self._set_container_sizes() + self._set_dashboard_size() def remove(self, box_id): """ @@ -499,17 +542,16 @@ def remove(self, box_id): ``` import plotly.dashboard_objs as dashboard - box_1 = { + box_a = { 'type': 'box', 'boxType': 'plot', 'fileId': 'username:some#', - 'title': 'box 1' + 'title': 'box a' } my_dboard = dashboard.Dashboard() - my_dboard.insert(box_1) + my_dboard.insert(box_a) my_dboard.remove(1) - my_dboard.get_preview() ``` """ @@ -530,7 +572,7 @@ def remove(self, box_id): else: self['layout'] = None - self._set_container_sizes() + self._set_dashboard_size() def swap(self, box_id_1, box_id_2): """ @@ -540,23 +582,23 @@ def swap(self, box_id_1, box_id_2): ``` import plotly.dashboard_objs as dashboard - box_1 = { + box_a = { 'type': 'box', 'boxType': 'plot', 'fileId': 'username:first#', - 'title': 'first box' + 'title': 'box a' } - box_2 = { + box_b = { 'type': 'box', 'boxType': 'plot', 'fileId': 'username:second#', - 'title': 'second box' + 'title': 'box b' } my_dboard = dashboard.Dashboard() - my_dboard.insert(box_1) - my_dboard.insert(box_2, 'above', 1) + my_dboard.insert(box_a) + my_dboard.insert(box_b, 'above', 1) # check box at box id 1 box_at_1 = my_dboard.get_box(1) @@ -569,16 +611,14 @@ def swap(self, box_id_1, box_id_2): ``` """ box_ids_to_path = self._compute_box_ids() - box_1 = self.get_box(box_id_1) - box_2 = self.get_box(box_id_2) + box_a = self.get_box(box_id_1) + box_b = self.get_box(box_id_2) - box_1_path = box_ids_to_path[box_id_1] - box_2_path = box_ids_to_path[box_id_2] + box_a_path = box_ids_to_path[box_id_1] + box_b_path = box_ids_to_path[box_id_2] - for pairs in [(box_1_path, box_2), (box_2_path, box_1)]: + for pairs in [(box_a_path, box_b), (box_b_path, box_a)]: loc_in_dashboard = self['layout'] for first_second in pairs[0][:-1]: loc_in_dashboard = loc_in_dashboard[first_second] loc_in_dashboard[pairs[0][-1]] = pairs[1] - - self._set_container_sizes() diff --git a/plotly/figure_factory/_county_choropleth.py b/plotly/figure_factory/_county_choropleth.py index cb542064dd..cc70eeb9fe 100644 --- a/plotly/figure_factory/_county_choropleth.py +++ b/plotly/figure_factory/_county_choropleth.py @@ -300,6 +300,8 @@ def _intervals_as_labels(array_of_intervals, round_legend_values, exponent_forma def _calculations(df, fips, values, index, f, simplify_county, level, x_centroids, y_centroids, centroid_text, x_traces, y_traces, fips_polygon_map): + # 0-pad FIPS code to ensure exactly 5 digits + padded_f = str(f).zfill(5) if fips_polygon_map[f].type == 'Polygon': x = fips_polygon_map[f].simplify( simplify_county @@ -311,10 +313,11 @@ def _calculations(df, fips, values, index, f, simplify_county, level, x_c, y_c = fips_polygon_map[f].centroid.xy county_name_str = str(df[df['FIPS'] == f]['COUNTY_NAME'].iloc[0]) state_name_str = str(df[df['FIPS'] == f]['STATE_NAME'].iloc[0]) + t_c = ( 'County: ' + county_name_str + '
' + 'State: ' + state_name_str + '
' + - 'FIPS: ' + str(f) + '
Value: ' + str(values[index]) + 'FIPS: ' + padded_f + '
Value: ' + str(values[index]) ) x_centroids.append(x_c[0]) @@ -337,7 +340,7 @@ def _calculations(df, fips, values, index, f, simplify_county, level, text = ( 'County: ' + county_name_str + '
' + 'State: ' + state_name_str + '
' + - 'FIPS: ' + str(f) + '
Value: ' + str(values[index]) + 'FIPS: ' + padded_f + '
Value: ' + str(values[index]) ) t_c = [text for poly in fips_polygon_map[f]] x_centroids = x_c + x_centroids @@ -352,12 +355,11 @@ def _calculations(df, fips, values, index, f, simplify_county, level, def create_choropleth(fips, values, scope=['usa'], binning_endpoints=None, colorscale=None, order=None, simplify_county=0.02, - simplify_state=0.02, asp=None, offline_mode=False, - show_hover=True, show_state_data=True, - state_outline=None, county_outline=None, - centroid_marker=None, round_legend_values=False, - exponent_format=False, legend_title='', - **layout_options): + simplify_state=0.02, asp=None, show_hover=True, + show_state_data=True, state_outline=None, + county_outline=None, centroid_marker=None, + round_legend_values=False, exponent_format=False, + legend_title='', **layout_options): """ Returns figure for county choropleth. Uses data from package_data. @@ -399,12 +401,6 @@ def create_choropleth(fips, values, scope=['usa'], binning_endpoints=None, Default = 0.02 :param (float) asp: the width-to-height aspect ratio for the camera. Default = 2.5 - :param (bool) offline_mode: if set to True, the centroids of each county - are invisible until selected over with a dragbox. Warning: this can - only be used if you are plotting in offline mode with validate set to - False as the params that are being added to the fig dictionary are not - yet part of the plotly.py python library. Stay tuned for updates. - Default = False :param (bool) show_hover: show county hover and centroid info :param (bool) show_state_data: reveals state boundary lines :param (dict) state_outline: dict of attributes of the state outline @@ -416,8 +412,9 @@ def create_choropleth(fips, values, scope=['usa'], binning_endpoints=None, https://plot.ly/python/reference/#scatter-marker-line for all valid params :param (dict) centroid_marker: dict of attributes of the centroid marker. - See https://plot.ly/python/reference/#scatter-marker for all valid - params + The centroid markers are invisible by default and appear visible on + selection. See https://plot.ly/python/reference/#scatter-marker for + all valid params :param (bool) round_legend_values: automatically round the numbers that appear in the legend to the nearest integer. Default = False @@ -587,9 +584,11 @@ def create_choropleth(fips, values, scope=['usa'], binning_endpoints=None, county_outline = {'color': 'rgb(0, 0, 0)', 'width': 0} if not centroid_marker: - centroid_marker = {'size': 2, - 'color': 'rgb(255, 255, 255)', - 'opacity': 0} + centroid_marker = {'size': 3, 'color': 'white', 'opacity': 1} + + # ensure centroid markers appear on selection + if 'opacity' not in centroid_marker: + centroid_marker.update({'opacity': 1}) if len(fips) != len(values): raise exceptions.PlotlyError( @@ -788,7 +787,7 @@ def create_choropleth(fips, values, scope=['usa'], binning_endpoints=None, fill='toself', fillcolor=color_lookup[lev], name=lev, - hoverinfo='text', + hoverinfo='none', ) plot_data.append(county_data) @@ -802,19 +801,14 @@ def create_choropleth(fips, values, scope=['usa'], binning_endpoints=None, text=centroid_text, name='US Counties', mode='markers', - marker=centroid_marker, + marker={'color': 'white', 'opacity': 0}, hoverinfo='text' ) - if offline_mode: - centroids_on_select = dict( - selected=dict( - marker=dict(size=2, color='white', opacity=1) - ), - unselected=dict( - marker=dict(opacity=0) - ) - ) - hover_points.update(centroids_on_select) + centroids_on_select = dict( + selected=dict(marker=centroid_marker), + unselected=dict(marker=dict(opacity=0)) + ) + hover_points.update(centroids_on_select) plot_data.append(hover_points) if show_state_data: diff --git a/plotly/tests/test_core/test_dashboard/test_dashboard.py b/plotly/tests/test_core/test_dashboard/test_dashboard.py index d984b690f5..494f4618f8 100644 --- a/plotly/tests/test_core/test_dashboard/test_dashboard.py +++ b/plotly/tests/test_core/test_dashboard/test_dashboard.py @@ -111,7 +111,7 @@ def test_dashboard_dict(self): } dash = dashboard.Dashboard() - dash.insert(my_box, '', 0) + dash.insert(my_box) dash.insert(my_box, 'above', 1) expected_dashboard = { @@ -131,9 +131,9 @@ def test_dashboard_dict(self): 'sizeUnit': '%', 'type': 'split'}, 'second': {'boxType': 'empty', 'type': 'box'}, - 'size': 1000, - 'sizeUnit': 'px', - 'type': 'split'}, + 'size': 1500, + 'sizeUnit': 'px', + 'type': 'split'}, 'settings': {}, 'version': 2 } diff --git a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_county_500k/cb_2016_us_county_500k.dbf b/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_county_500k/cb_2016_us_county_500k.dbf deleted file mode 100644 index 1ef3b1499f..0000000000 Binary files a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_county_500k/cb_2016_us_county_500k.dbf and /dev/null differ diff --git a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_county_500k/cb_2016_us_county_500k.shp b/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_county_500k/cb_2016_us_county_500k.shp deleted file mode 100644 index 45b3f041f3..0000000000 Binary files a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_county_500k/cb_2016_us_county_500k.shp and /dev/null differ diff --git a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_county_500k/cb_2016_us_county_500k.shx b/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_county_500k/cb_2016_us_county_500k.shx deleted file mode 100644 index 715e770c75..0000000000 Binary files a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_county_500k/cb_2016_us_county_500k.shx and /dev/null differ diff --git a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_state_500k/cb_2016_us_state_500k.dbf b/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_state_500k/cb_2016_us_state_500k.dbf deleted file mode 100755 index c3e3b13e21..0000000000 Binary files a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_state_500k/cb_2016_us_state_500k.dbf and /dev/null differ diff --git a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_state_500k/cb_2016_us_state_500k.shp b/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_state_500k/cb_2016_us_state_500k.shp deleted file mode 100755 index f2a32cd6a2..0000000000 Binary files a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_state_500k/cb_2016_us_state_500k.shp and /dev/null differ diff --git a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_state_500k/cb_2016_us_state_500k.shx b/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_state_500k/cb_2016_us_state_500k.shx deleted file mode 100755 index 95347eb02d..0000000000 Binary files a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/cb_2016_us_state_500k/cb_2016_us_state_500k.shx and /dev/null differ diff --git a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/gz_2010_us_050_00_500k/gz_2010_us_050_00_500k.dbf b/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/gz_2010_us_050_00_500k/gz_2010_us_050_00_500k.dbf deleted file mode 100755 index 8397f541ec..0000000000 Binary files a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/gz_2010_us_050_00_500k/gz_2010_us_050_00_500k.dbf and /dev/null differ diff --git a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/gz_2010_us_050_00_500k/gz_2010_us_050_00_500k.shp b/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/gz_2010_us_050_00_500k/gz_2010_us_050_00_500k.shp deleted file mode 100755 index a1177e7b3c..0000000000 Binary files a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/gz_2010_us_050_00_500k/gz_2010_us_050_00_500k.shp and /dev/null differ diff --git a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/gz_2010_us_050_00_500k/gz_2010_us_050_00_500k.shx b/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/gz_2010_us_050_00_500k/gz_2010_us_050_00_500k.shx deleted file mode 100755 index 85675d9254..0000000000 Binary files a/plotly/tests/test_optional/test_figure_factory/plotly/package_data/data/gz_2010_us_050_00_500k/gz_2010_us_050_00_500k.shx and /dev/null differ