Skip to content
Open
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ before_install:
- conda config --set always_yes yes --set changeps1 no
- conda update -q conda
- conda info -a
- conda create -q -n test-environment python=$PYTHON_VERSION numpy scipy runipy
- conda create -q -n test-environment python=$PYTHON_VERSION numpy scipy runipy matplotlib
- source activate test-environment
- conda install -c conda-forge pytest==3.8.1 pytest-cov bokeh nodejs matplotlib scikit-image shapely flake8
- pip install PyChromeDevTools
Expand Down
125 changes: 120 additions & 5 deletions ipyvolume/transferfunction.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@

from __future__ import absolute_import

__all__ = ['TransferFunction', 'TransferFunctionJsBumps', 'TransferFunctionWidgetJs3', 'TransferFunctionWidget3']

import ipywidgets as widgets
import matplotlib.colors
import matplotlib.cm
import numpy as np
import ipywidgets as widgets # we should not have widgets under two names
import traitlets
from traitlets import Unicode
from traitlets import Unicode, validate
from traittypes import Array

from . import serialize
import ipyvolume._version
from ipyvolume import serialize

__all__ = ['TransferFunction', 'TransferFunctionJsBumps', 'TransferFunctionWidgetJs3', 'TransferFunctionWidget3']

N = 1024
x = np.linspace(0, 1, N, endpoint=True)
Expand Down Expand Up @@ -136,3 +137,117 @@ def control(self, max_opacity=0.2):
widgets.HBox([widgets.Label(value="opacities:"), o1, o2, o3]),
]
)


def linear_transfer_function(color,
min_opacity=0,
max_opacity=0.05,
reverse_opacity=False,
n_elements = 256):
"""Transfer function of a single color and linear opacity.

:param color: Listlike RGB, or string with hexidecimal or named color.
RGB values should be within 0-1 range.
:param min_opacity: Minimum opacity, default value is 0.0.
Lowest possible value is 0.0, optional.
:param max_opacity: Maximum opacity, default value is 0.05.
Highest possible value is 1.0, optional.
:param reverse_opacity: Linearly decrease opacity, optional.
:param n_elements: Length of rgba array transfer function attribute.
:type color: listlike or string
:type min_opacity: float, int
:type max_opacity: float, int
:type reverse_opacity: bool
:type n_elements: int
:return: transfer_function
:rtype: ipyvolume TransferFunction

:Example:
>>> import ipyvolume as ipv
>>> green_tf = ipv.transfer_function.linear_transfer_function('green')
>>> ds = ipv.datasets.aquariusA2.fetch()
>>> ipv.volshow(ds.data[::4,::4,::4], tf=green_tf)
>>> ipv.show()

.. seealso:: matplotlib_transfer_function()
"""
r, g, b = matplotlib.colors.to_rgb(color)
opacity = np.linspace(min_opacity, max_opacity, num=n_elements)
if reverse_opacity:
opacity = np.flip(opacity, axis=0)
rgba = np.transpose(np.stack([[r] * n_elements,
[g] * n_elements,
[b] * n_elements,
opacity]))
transfer_function = TransferFunction(rgba=rgba)
return transfer_function


def matplotlib_transfer_function(colormap_name,
min_opacity=0,
max_opacity=0.05,
reverse_colormap=False,
reverse_opacity=False,
n_elements=256):
"""Transfer function from matplotlib colormaps.

:param colormap_name: name of matplotlib colormap
:param min_opacity: Minimum opacity, default value is 0.
Lowest possible value is 0, optional.
:param max_opacity: Maximum opacity, default value is 0.05.
Highest possible value is 1.0, optional.
:param reverse_colormap: reversed matplotlib colormap, optional.
:param reverse_opacity: Linearly decrease opacity, optional.
:param n_elements: Length of rgba array transfer function attribute.
:type colormap_name: str
:type min_opacity: float, int
:type max_opacity: float, int
:type reverse_colormap: bool
:type reverse_opacity: bool
:type n_elements: int
:return: transfer_function
:rtype: ipyvolume TransferFunction

:Example:
>>> import ipyvolume as ipv
>>> rgb = (0, 255, 0) # RGB value for green
>>> green_tf = ipv.transfer_function.matplotlib_transfer_function('bone')
>>> ds = ipv.datasets.aquariusA2.fetch()
>>> ipv.volshow(ds.data[::4,::4,::4], tf=green_tf)
>>> ipv.show()

.. seealso:: linear_transfer_function()
"""
cmap = matplotlib.cm.get_cmap(name=colormap_name)
rgba = np.array([cmap(i) for i in np.linspace(0, 1, n_elements)])
if reverse_colormap:
rgba = np.flip(rgba, axis=0)
# Create opacity values to overwrite default matplotlib opacity=1.0
opacity = np.linspace(min_opacity, max_opacity, num=n_elements)
if reverse_opacity:
opacity = np.flip(opacity, axis=0)
rgba[:,-1] = opacity # replace opacity=1 with actual opacity
transfer_function = TransferFunction(rgba=rgba)
return transfer_function


def predefined_transfer_functions():
"""Load predefined transfer functions into a dictionary.

:return: dictionary of predefined transfer functions.
:rtype: dict of ipyvolume TransferFunction instances
"""
transfer_functions = {}
# RGB primary and secondary colors
colors = ['red', 'green', 'blue', 'yellow', 'magenta', 'cyan',
'black', 'gray', 'white']
for color in colors:
tf = linear_transfer_function(color)
transfer_functions[color] = tf
tf_reversed = linear_transfer_function(rgb, reverse_opacity=True)
transfer_functions[color_key + '_r'] = tf_reversed
# All matplotlib colormaps
matplotlib_colormaps = matplotlib.cm.cmap_d.keys()
for colormap in matplotlib_colormaps:
transfer_functions[colormap] = matplotlib_transfer_function(colormap)
return transfer_functions