Skip to content

Commit c03e18a

Browse files
authored
Merge pull request #531 from plotly/trisurf_colorbar
Trisurf colorbar
2 parents 0af4ef6 + a53e595 commit c03e18a

File tree

3 files changed

+82
-17
lines changed

3 files changed

+82
-17
lines changed

plotly/graph_reference/default-schema.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@
112112
"requiredOpts": []
113113
},
114114
"subplotid": {
115-
"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', ...",
116-
"otherOpts": [
115+
"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', ...",
116+
"otherOpts": [],
117+
"requiredOpts": [
117118
"dflt"
118-
],
119-
"requiredOpts": []
119+
]
120120
}
121121
}
122122
},
@@ -18262,5 +18262,6 @@
1826218262
},
1826318263
"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`."
1826418264
}
18265-
}
18265+
},
18266+
"transforms": {}
1826618267
}

plotly/tools.py

+75-11
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,50 @@ class FigureFactory(object):
14761476
more information and examples of a specific chart type.
14771477
"""
14781478

1479+
@staticmethod
1480+
def _make_colorscale(colors, scale=None):
1481+
"""
1482+
Makes a colorscale from a list of colors and scale
1483+
1484+
Takes a list of colors and scales and constructs a colorscale based
1485+
on the colors in sequential order. If 'scale' is left empty, a linear-
1486+
interpolated colorscale will be generated. If 'scale' is a specificed
1487+
list, it must be the same legnth as colors and must contain all floats
1488+
For documentation regarding to the form of the output, see
1489+
https://plot.ly/python/reference/#mesh3d-colorscale
1490+
"""
1491+
colorscale = []
1492+
1493+
if not scale:
1494+
for j, color in enumerate(colors):
1495+
colorscale.append([j * 1./(len(colors) - 1), color])
1496+
return colorscale
1497+
1498+
else:
1499+
colorscale = [list(tup) for tup in zip(scale, colors)]
1500+
return colorscale
1501+
1502+
@staticmethod
1503+
def _convert_colorscale_to_rgb(colorscale):
1504+
"""
1505+
Converts the colors in a colorscale to rgb colors
1506+
1507+
A colorscale is an array of arrays, each with a numeric value as the
1508+
first item and a color as the second. This function specifically is
1509+
converting a colorscale with tuple colors (each coordinate between 0
1510+
and 1) into a colorscale with the colors transformed into rgb colors
1511+
"""
1512+
for color in colorscale:
1513+
color[1] = FigureFactory._convert_to_RGB_255(
1514+
color[1]
1515+
)
1516+
1517+
for color in colorscale:
1518+
color[1] = FigureFactory._label_rgb(
1519+
color[1]
1520+
)
1521+
return colorscale
1522+
14791523
@staticmethod
14801524
def _make_linear_colorscale(colors):
14811525
"""
@@ -3141,7 +3185,7 @@ def _find_intermediate_color(lowcolor, highcolor, intermed):
31413185
@staticmethod
31423186
def _color_parser(colors, function):
31433187
"""
3144-
Takes color(s) and a function and applys the function on the color(s)
3188+
Takes color(s) and a function and applies the function on the color(s)
31453189
31463190
In particular, this function identifies whether the given color object
31473191
is an iterable or not and applies the given color-parsing function to
@@ -3226,9 +3270,9 @@ def _map_face2color(face, colormap, vmin, vmax):
32263270
return face_color
32273271

32283272
@staticmethod
3229-
def _trisurf(x, y, z, simplices, colormap=None, color_func=None,
3230-
plot_edges=False, x_edge=None, y_edge=None, z_edge=None,
3231-
facecolor=None):
3273+
def _trisurf(x, y, z, simplices, show_colorbar, colormap=None,
3274+
color_func=None, plot_edges=False, x_edge=None, y_edge=None,
3275+
z_edge=None, facecolor=None):
32323276
"""
32333277
Refer to FigureFactory.create_trisurf() for docstring
32343278
"""
@@ -3293,11 +3337,26 @@ def _trisurf(x, y, z, simplices, colormap=None, color_func=None,
32933337
# Make sure we have arrays to speed up plotting
32943338
facecolor = np.asarray(facecolor)
32953339
ii, jj, kk = simplices.T
3340+
3341+
# make a colorscale from the colors
3342+
colorscale = FigureFactory._make_colorscale(colormap)
3343+
colorscale = FigureFactory._convert_colorscale_to_rgb(colorscale)
3344+
32963345
triangles = graph_objs.Mesh3d(x=x, y=y, z=z, facecolor=facecolor,
32973346
i=ii, j=jj, k=kk, name='')
32983347

3299-
if plot_edges is not True: # the triangle sides are not plotted
3300-
return graph_objs.Data([triangles])
3348+
colorbar = graph_objs.Mesh3d(x=[0, 1], y=[0, 1], z=[0, 1],
3349+
colorscale=colorscale,
3350+
intensity=[0, 1],
3351+
showscale=True)
3352+
3353+
# the triangle sides are not plotted
3354+
if plot_edges is not True:
3355+
if show_colorbar is True:
3356+
return graph_objs.Data([triangles, colorbar])
3357+
else:
3358+
return graph_objs.Data([triangles])
3359+
33013360

33023361
# define the lists x_edge, y_edge and z_edge, of x, y, resp z
33033362
# coordinates of edge end points for each triangle
@@ -3337,12 +3396,14 @@ def _trisurf(x, y, z, simplices, colormap=None, color_func=None,
33373396
line=graph_objs.Line(color='rgb(50, 50, 50)',
33383397
width=1.5)
33393398
)
3340-
3341-
return graph_objs.Data([triangles, lines])
3399+
if show_colorbar is True:
3400+
return graph_objs.Data([triangles, lines, colorbar])
3401+
else:
3402+
return graph_objs.Data([triangles, lines])
33423403

33433404
@staticmethod
3344-
def create_trisurf(x, y, z, simplices, colormap=None, color_func=None,
3345-
title='Trisurf Plot', plot_edges=True,
3405+
def create_trisurf(x, y, z, simplices, colormap=None, show_colorbar=True,
3406+
color_func=None, title='Trisurf Plot', plot_edges=True,
33463407
showbackground=True,
33473408
backgroundcolor='rgb(230, 230, 230)',
33483409
gridcolor='rgb(255, 255, 255)',
@@ -3363,7 +3424,8 @@ def create_trisurf(x, y, z, simplices, colormap=None, color_func=None,
33633424
of the form 'rgb(x, y, z)' where x, y, z belong to the interval
33643425
[0, 255] and a color tuple is a tuple of the form (a, b, c) where
33653426
a, b and c belong to [0, 1]. If colormap is a list, it must
3366-
contain the valid color types aforementioned as its members.
3427+
contain the valid color types aforementioned as its members
3428+
:param (bool) show_colorbar: determines if colorbar is visible
33673429
:param (function|list) color_func: The parameter that determines the
33683430
coloring of the surface. Takes either a function with 3 arguments
33693431
x, y, z or a list/array of color values the same length as
@@ -3572,6 +3634,7 @@ def dist_origin(x, y, z):
35723634
colormap = FigureFactory._validate_colors(colormap, 'tuple')
35733635

35743636
data1 = FigureFactory._trisurf(x, y, z, simplices,
3637+
show_colorbar=show_colorbar,
35753638
color_func=color_func,
35763639
colormap=colormap,
35773640
plot_edges=plot_edges)
@@ -3595,6 +3658,7 @@ def dist_origin(x, y, z):
35953658
z=aspectratio['z']),
35963659
)
35973660
)
3661+
35983662
return graph_objs.Figure(data=data1, layout=layout)
35993663

36003664
@staticmethod

plotly/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.12.4'
1+
__version__ = '1.12.5'

0 commit comments

Comments
 (0)