diff --git a/plotly/graph_reference/default-schema.json b/plotly/graph_reference/default-schema.json index ed1b0407183..db24b739d2d 100644 --- a/plotly/graph_reference/default-schema.json +++ b/plotly/graph_reference/default-schema.json @@ -112,11 +112,11 @@ "requiredOpts": [] }, "subplotid": { - "description": "An id string of a subplot type (given by dflt), optionally followed by an integer >1. e.g. if dflt='geo', we can have 'geo', 'geo2', 'geo3', ...", - "otherOpts": [ + "description": "An id string of a subplot type (given by dflt), optionally followed by an integer >1. e.g. if dflt='geo', we can have 'geo', 'geo2', 'geo3', ...", + "otherOpts": [], + "requiredOpts": [ "dflt" - ], - "requiredOpts": [] + ] } } }, @@ -18262,5 +18262,6 @@ }, "description": "The data the describes the coordinates of the surface is set in `z`. Data in `z` should be a {2D array}. Coordinates in `x` and `y` can either be 1D {arrays} or {2D arrays} (e.g. to graph parametric surfaces). If not provided in `x` and `y`, the x and y coordinates are assumed to be linear starting at 0 with a unit step. The color scale corresponds to the `z` values by default. For custom color scales, use `surfacecolor` which should be a {2D array}, where its bounds can be controlled using `cmin` and `cmax`." } - } + }, + "transforms": {} } \ No newline at end of file diff --git a/plotly/tools.py b/plotly/tools.py index 8e874768dde..e276575d4f3 100644 --- a/plotly/tools.py +++ b/plotly/tools.py @@ -1476,6 +1476,50 @@ class FigureFactory(object): more information and examples of a specific chart type. """ + @staticmethod + def _make_colorscale(colors, scale=None): + """ + Makes a colorscale from a list of colors and scale + + Takes a list of colors and scales and constructs a colorscale based + on the colors in sequential order. If 'scale' is left empty, a linear- + interpolated colorscale will be generated. If 'scale' is a specificed + list, it must be the same legnth as colors and must contain all floats + For documentation regarding to the form of the output, see + https://plot.ly/python/reference/#mesh3d-colorscale + """ + colorscale = [] + + if not scale: + for j, color in enumerate(colors): + colorscale.append([j * 1./(len(colors) - 1), color]) + return colorscale + + else: + colorscale = [list(tup) for tup in zip(scale, colors)] + return colorscale + + @staticmethod + def _convert_colorscale_to_rgb(colorscale): + """ + Converts the colors in a colorscale to rgb colors + + A colorscale is an array of arrays, each with a numeric value as the + first item and a color as the second. This function specifically is + converting a colorscale with tuple colors (each coordinate between 0 + and 1) into a colorscale with the colors transformed into rgb colors + """ + for color in colorscale: + color[1] = FigureFactory._convert_to_RGB_255( + color[1] + ) + + for color in colorscale: + color[1] = FigureFactory._label_rgb( + color[1] + ) + return colorscale + @staticmethod def _make_linear_colorscale(colors): """ @@ -3141,7 +3185,7 @@ def _find_intermediate_color(lowcolor, highcolor, intermed): @staticmethod def _color_parser(colors, function): """ - Takes color(s) and a function and applys the function on the color(s) + Takes color(s) and a function and applies the function on the color(s) In particular, this function identifies whether the given color object is an iterable or not and applies the given color-parsing function to @@ -3226,9 +3270,9 @@ def _map_face2color(face, colormap, vmin, vmax): return face_color @staticmethod - def _trisurf(x, y, z, simplices, colormap=None, color_func=None, - plot_edges=False, x_edge=None, y_edge=None, z_edge=None, - facecolor=None): + def _trisurf(x, y, z, simplices, show_colorbar, colormap=None, + color_func=None, plot_edges=False, x_edge=None, y_edge=None, + z_edge=None, facecolor=None): """ Refer to FigureFactory.create_trisurf() for docstring """ @@ -3293,11 +3337,26 @@ def _trisurf(x, y, z, simplices, colormap=None, color_func=None, # Make sure we have arrays to speed up plotting facecolor = np.asarray(facecolor) ii, jj, kk = simplices.T + + # make a colorscale from the colors + colorscale = FigureFactory._make_colorscale(colormap) + colorscale = FigureFactory._convert_colorscale_to_rgb(colorscale) + triangles = graph_objs.Mesh3d(x=x, y=y, z=z, facecolor=facecolor, i=ii, j=jj, k=kk, name='') - if plot_edges is not True: # the triangle sides are not plotted - return graph_objs.Data([triangles]) + colorbar = graph_objs.Mesh3d(x=[0, 1], y=[0, 1], z=[0, 1], + colorscale=colorscale, + intensity=[0, 1], + showscale=True) + + # the triangle sides are not plotted + if plot_edges is not True: + if show_colorbar is True: + return graph_objs.Data([triangles, colorbar]) + else: + return graph_objs.Data([triangles]) + # define the lists x_edge, y_edge and z_edge, of x, y, resp z # coordinates of edge end points for each triangle @@ -3337,12 +3396,14 @@ def _trisurf(x, y, z, simplices, colormap=None, color_func=None, line=graph_objs.Line(color='rgb(50, 50, 50)', width=1.5) ) - - return graph_objs.Data([triangles, lines]) + if show_colorbar is True: + return graph_objs.Data([triangles, lines, colorbar]) + else: + return graph_objs.Data([triangles, lines]) @staticmethod - def create_trisurf(x, y, z, simplices, colormap=None, color_func=None, - title='Trisurf Plot', plot_edges=True, + def create_trisurf(x, y, z, simplices, colormap=None, show_colorbar=True, + color_func=None, title='Trisurf Plot', plot_edges=True, showbackground=True, backgroundcolor='rgb(230, 230, 230)', gridcolor='rgb(255, 255, 255)', @@ -3363,7 +3424,8 @@ def create_trisurf(x, y, z, simplices, colormap=None, color_func=None, of the form 'rgb(x, y, z)' where x, y, z belong to the interval [0, 255] and a color tuple is a tuple of the form (a, b, c) where a, b and c belong to [0, 1]. If colormap is a list, it must - contain the valid color types aforementioned as its members. + contain the valid color types aforementioned as its members + :param (bool) show_colorbar: determines if colorbar is visible :param (function|list) color_func: The parameter that determines the coloring of the surface. Takes either a function with 3 arguments x, y, z or a list/array of color values the same length as @@ -3572,6 +3634,7 @@ def dist_origin(x, y, z): colormap = FigureFactory._validate_colors(colormap, 'tuple') data1 = FigureFactory._trisurf(x, y, z, simplices, + show_colorbar=show_colorbar, color_func=color_func, colormap=colormap, plot_edges=plot_edges) @@ -3595,6 +3658,7 @@ def dist_origin(x, y, z): z=aspectratio['z']), ) ) + return graph_objs.Figure(data=data1, layout=layout) @staticmethod diff --git a/plotly/version.py b/plotly/version.py index aba17a1d85e..bf838c22f22 100644 --- a/plotly/version.py +++ b/plotly/version.py @@ -1 +1 @@ -__version__ = '1.12.4' +__version__ = '1.12.5'