diff --git a/doc/examples/plot_label.py b/doc/examples/plot_label.py index dd3e777d..f80271ce 100644 --- a/doc/examples/plot_label.py +++ b/doc/examples/plot_label.py @@ -19,7 +19,8 @@ import matplotlib.patches as mpatches from skimage import data from skimage.filters import threshold_otsu from skimage.segmentation import clear_border -from skimage.morphology import label, closing, square +from skimage.measure import label +from skimage.morphology import closing, square from skimage.measure import regionprops from skimage.color import label2rgb diff --git a/doc/examples/plot_regionprops.py b/doc/examples/plot_regionprops.py index 065bae55..c4a8fc29 100644 --- a/doc/examples/plot_regionprops.py +++ b/doc/examples/plot_regionprops.py @@ -11,8 +11,7 @@ import matplotlib.pyplot as plt import numpy as np from skimage.draw import ellipse -from skimage.morphology import label -from skimage.measure import regionprops +from skimage.measure import label, regionprops from skimage.transform import rotate diff --git a/doc/examples/plot_tinting_grayscale_images.py b/doc/examples/plot_tinting_grayscale_images.py index f3ff5466..f4dde6fd 100644 --- a/doc/examples/plot_tinting_grayscale_images.py +++ b/doc/examples/plot_tinting_grayscale_images.py @@ -37,7 +37,7 @@ ax2.imshow(yellow_multiplier * image) In many cases, dealing with RGB values may not be ideal. Because of that, there are many other `color spaces`_ in which you can represent a color image. One -popular color space is called HSV_, which represents hue (~the color), +popular color space is called HSV, which represents hue (~the color), saturation (~colorfulness), and value (~brightness). For example, a color (hue) might be green, but its saturation is how intense that green is---where olive is on the low end and neon on the high end. @@ -46,6 +46,9 @@ In some implementations, the hue in HSV goes from 0 to 360, since hues wrap around in a circle. In scikit-image, however, hues are float values from 0 to 1, so that hue, saturation, and value all share the same scale. +.. _color spaces: + http://en.wikipedia.org/wiki/List_of_color_spaces_and_their_uses + Below, we plot a linear gradient in the hue, with the saturation and value turned all the way up: """ @@ -69,6 +72,8 @@ Notice how the colors at the far left and far right are the same. That reflects the fact that the hues wrap around like the color wheel (see HSV_ for more info). +.. _HSV: http://en.wikipedia.org/wiki/HSL_and_HSV + Now, let's create a little utility function to take an RGB image and: 1. Transform the RGB image to HSV @@ -147,7 +152,4 @@ plt.show() For coloring multiple regions, you may also be interested in `skimage.color.label2rgb `_. -.. _color spaces: - http://en.wikipedia.org/wiki/List_of_color_spaces_and_their_uses -.. _HSV: http://en.wikipedia.org/wiki/HSL_and_HSV """ diff --git a/doc/examples/plot_windowed_histogram.py b/doc/examples/plot_windowed_histogram.py index ebd6ea2f..65e67706 100644 --- a/doc/examples/plot_windowed_histogram.py +++ b/doc/examples/plot_windowed_histogram.py @@ -60,10 +60,12 @@ def windowed_histogram_similarity(image, selem, reference_hist, n_bins): # a measure of distance between histograms X = px_histograms Y = reference_hist + num = (X - Y) ** 2 denom = X + Y + denom[denom == 0] = np.infty frac = num / denom - frac[denom == 0] = 0 + chi_sqr = 0.5 * np.sum(frac, axis=2) # Generate a similarity measure. It needs to be low when distance is high diff --git a/doc/ext/plot2rst.py b/doc/ext/plot2rst.py index 268ddb63..0b618b3b 100644 --- a/doc/ext/plot2rst.py +++ b/doc/ext/plot2rst.py @@ -66,10 +66,12 @@ Suggested CSS definitions """ import os +import re import shutil import token import tokenize import traceback +import itertools import numpy as np import matplotlib @@ -83,7 +85,7 @@ from skimage.util.dtype import dtype_range from notebook import Notebook from docutils.core import publish_parts - +from sphinx.domains.python import PythonDomain LITERALINCLUDE = """ .. literalinclude:: {src_name} @@ -332,6 +334,8 @@ def write_example(src_name, src_dir, rst_dir, cfg): notebook_path.exists: return + print('plot2rst: %s' % basename) + blocks = split_code_and_text_blocks(example_file) if blocks[0][2].startswith('#!'): blocks.pop(0) # don't add shebang line to rst file. @@ -380,15 +384,57 @@ def write_example(src_name, src_dir, rst_dir, cfg): # Export example to IPython notebook nb = Notebook() - for (cell_type, _, content) in blocks: - content = content.rstrip('\n') + # Add sphinx roles to the examples, otherwise docutils + # cannot compile the ReST for the notebook + sphinx_roles = PythonDomain.roles.keys() + preamble = '\n'.join('.. role:: py:{0}(literal)\n'.format(role) + for role in sphinx_roles) + # Grab all references to inject them in cells where needed + ref_regexp = re.compile('\n(\.\. \[(\d+)\].*(?:\n[ ]{7,8}.*)+)') + math_role_regexp = re.compile(':math:`(.*?)`') + + text = '\n'.join((content for (cell_type, _, content) in blocks + if cell_type != 'code')) + + references = re.findall(ref_regexp, text) + + for (cell_type, _, content) in blocks: if cell_type == 'code': nb.add_cell(content, cell_type='code') else: - content = content.replace('"""', '') + if content.startswith('r'): + content = content.replace('r"""', '') + escaped = False + else: + content = content.replace('"""', '') + escaped = True + + if not escaped: + content = content.replace("\\", "\\\\") + + content = content.replace('.. seealso::', '**See also:**') + content = re.sub(math_role_regexp, r'$\1$', content) + + # Remove math directive when rendering notebooks + # until we implement a smarter way of capturing and replacing + # its content + content = content.replace('.. math::', '') + + if not content.strip(): + continue + + content = (preamble + content).rstrip('\n') content = '\n'.join([line for line in content.split('\n') if not line.startswith('.. image')]) + + # Remove reference links until we can figure out a better way to + # preserve them + for (reference, ref_id) in references: + ref_tag = '[{0}]_'.format(ref_id) + if ref_tag in content: + content = content.replace(ref_tag, ref_tag[:-1]) + html = publish_parts(content, writer_name='html')['html_body'] nb.add_cell(html, cell_type='markdown') diff --git a/skimage/exposure/_adapthist.py b/skimage/exposure/_adapthist.py index b0c3b952..668d27a6 100644 --- a/skimage/exposure/_adapthist.py +++ b/skimage/exposure/_adapthist.py @@ -136,7 +136,7 @@ def _clahe(image, ntiles_x, ntiles_y, clip_limit, nbins=128): image = pad(image, ((0, h_pad), (0, w_pad)), mode='reflect') h_inner, w_inner = image.shape - bin_size = 1 + NR_OF_GREY / nbins + bin_size = 1 + NR_OF_GREY // nbins lut = np.arange(NR_OF_GREY) lut //= bin_size img_blocks = view_as_blocks(image, (height, width)) diff --git a/skimage/io/__init__.py b/skimage/io/__init__.py index a485250e..d0ec1f43 100644 --- a/skimage/io/__init__.py +++ b/skimage/io/__init__.py @@ -26,7 +26,7 @@ def _format_plugin_info_table(info_table, column_lengths): info_table.insert(0, _separator('=', column_lengths)) info_table.insert(1, ('Plugin', 'Description')) info_table.insert(2, _separator('-', column_lengths)) - info_table.append(_separator('-', column_lengths)) + info_table.append(_separator('=', column_lengths)) def _update_doc(doc): diff --git a/skimage/viewer/plugins/base.py b/skimage/viewer/plugins/base.py index 6b162fd8..def0bfd9 100644 --- a/skimage/viewer/plugins/base.py +++ b/skimage/viewer/plugins/base.py @@ -142,7 +142,7 @@ class Plugin(QtGui.QDialog): plugin += Widget(...) Widgets can adjust required or optional arguments of filter function or - parameters for the plugin. This is specified by the Widget's `ptype'. + parameters for the plugin. This is specified by the Widget's `ptype`. """ if widget.ptype == 'kwarg': name = widget.name.replace(' ', '_') diff --git a/skimage/viewer/plugins/color_histogram.py b/skimage/viewer/plugins/color_histogram.py index 99205c41..52c71786 100644 --- a/skimage/viewer/plugins/color_histogram.py +++ b/skimage/viewer/plugins/color_histogram.py @@ -73,14 +73,16 @@ class ColorHistogram(PlotPlugin): The selected pixels. data : dict The data describing the histogram and the selected region. - Keys: - - 'bins' : array of float, the bin boundaries for both - `a` and `b` channels. - - 'hist' : 2D array of float, the normalized histogram. - - 'edges' : tuple of array of float, the bin edges - along each dimension - - 'extents' : tuple of float, the left and right and - top and bottom of the selected region. + The dictionary contains: + + - 'bins' : array of float + The bin boundaries for both `a` and `b` channels. + - 'hist' : 2D array of float + The normalized histogram. + - 'edges' : tuple of array of float + The bin edges along each dimension + - 'extents' : tuple of float + The left and right and top and bottom of the selected region. """ return (self.mask, self.data) diff --git a/skimage/viewer/utils/core.py b/skimage/viewer/utils/core.py index 90521f9c..8aca4e24 100644 --- a/skimage/viewer/utils/core.py +++ b/skimage/viewer/utils/core.py @@ -72,16 +72,13 @@ class RequiredAttr(object): instances = dict() - def __init__(self, msg='Required attribute not set', init_val=None): + def __init__(self, init_val=None): self.instances[self, None] = init_val - self.msg = msg def __get__(self, obj, objtype): value = self.instances[self, obj] if value is None: - # Should raise an error but that causes issues with the buildbot. - warnings.warn(self.msg) - self.__set__(obj, self.init_val) + raise AttributeError('Required attribute not set') return value def __set__(self, obj, value):