def test_get_colorbar_and_data_ranges_with_vmin(): data = np.array([[-.5, 1., np.nan], [0., np.nan, -.2], [1.5, 2.5, 3.]]) with pytest.raises(ValueError, match='does not accept a "vmin" argument'): _get_colorbar_and_data_ranges(data, vmax=None, symmetric_cbar=True, kwargs={'vmin': 1.})
def test_get_colorbar_and_data_ranges_with_vmin(): """Tests for _get_colorbar_and_data_ranges. Tests that a ValueError is raised when vmin and symmetric_cbar are both provided. """ with pytest.raises(ValueError, match='does not accept a "vmin" argument'): _get_colorbar_and_data_ranges(data_pos_neg, vmax=None, symmetric_cbar=True, kwargs={'vmin': 1.})
def _add_colorbar(x, vmax, cmap): ''' add colorbar helper for _plot_hcp_style ''' cbar_vmin, cbar_vmax, vmin, vmax = ip._get_colorbar_and_data_ranges( x, vmax, symmetric_cbar='auto', kwargs='') print(np.min(x), np.max(x)) # overwrite variables vmin, threshold = 0, 0 #cmap = get_cmap('hot') cmap = get_cmap(cmap) norm = Normalize(vmin=vmin, vmax=vmax) cmaplist = [cmap(i) for i in range(cmap.N)] # set colors to grey for absolute values < threshold istart = int(norm(-threshold, clip=True) * (cmap.N - 1)) istop = int(norm(threshold, clip=True) * (cmap.N - 1)) for i in range(istart, istop): cmaplist[i] = (0.5, 0.5, 0.5, 1.) our_cmap = LinearSegmentedColormap.from_list('Custom cmap', cmaplist, cmap.N) sm = plt.cm.ScalarMappable(cmap=our_cmap, norm=plt.Normalize(vmin=vmin, vmax=vmax)) return sm
def _draw_colorbar( stat_map_img, axes, threshold=.1, nb_ticks=5, edge_color="0.5", edge_alpha=1, aspect=40, fraction=0.025, anchor=(10.0, 0.5), ): if isinstance(stat_map_img, str): stat_map_img = path.abspath(path.expanduser(stat_map_img)) stat_map_img = nib.load(stat_map_img) _, _, vmin, vmax, = _get_colorbar_and_data_ranges( _safe_get_data(stat_map_img, ensure_finite=True), None, "auto", "") cbar_ax, p_ax = make_axes( axes, aspect=aspect, fraction=fraction, # pad=-0.5, anchor=anchor, # panchor=(-110.0, 0.5), ) ticks = np.linspace(vmin, vmax, nb_ticks) bounds = np.linspace(vmin, vmax, MYMAP.N) norm = mcolors.Normalize(vmin=vmin, vmax=vmax) # some colormap hacking cmaplist = [MYMAP(i) for i in range(MYMAP.N)] istart = int(norm(-threshold, clip=True) * (MYMAP.N - 1)) istop = int(norm(threshold, clip=True) * (MYMAP.N - 1)) for i in range(istart, istop): cmaplist[i] = (0.5, 0.5, 0.5, 1.) # just an average gray color our_cmap = MYMAP.from_list('Custom cmap', cmaplist, MYMAP.N) cbar = ColorbarBase( cbar_ax, ticks=ticks, norm=norm, orientation="vertical", cmap=our_cmap, boundaries=bounds, spacing="proportional", format="%.2g", ) cbar.outline.set_edgecolor(edge_color) cbar.outline.set_alpha(edge_alpha) cbar_ax.yaxis.tick_left() tick_color = 'k' for tick in cbar_ax.yaxis.get_ticklabels(): tick.set_color(tick_color) cbar_ax.yaxis.set_tick_params(width=0) return cbar_ax, p_ax
def test_get_colorbar_and_data_ranges_masked_array(): # data with positive and negative range affine = np.eye(4) data = np.array([[-.5, 1., np.nan], [0., np.nan, -.2], [1.5, 2.5, 3.]]) masked_data = np.ma.masked_greater(data, 2.) # Easier to fill masked values with NaN to test against later on filled_data = masked_data.filled(np.nan) img = nibabel.Nifti1Image(masked_data, affine) # Reasonable additional arguments that would end up being passed # to imshow in a real plotting use case kwargs = {'aspect': 'auto', 'alpha': 0.9} # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=None, symmetric_cbar=True, kwargs=kwargs) assert_equal(vmin, -np.nanmax(filled_data)) assert_equal(vmax, np.nanmax(filled_data)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=2, symmetric_cbar=True, kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=None, symmetric_cbar=False, kwargs=kwargs) assert_equal(vmin, -np.nanmax(filled_data)) assert_equal(vmax, np.nanmax(filled_data)) assert_equal(cbar_vmin, np.nanmin(filled_data)) assert_equal(cbar_vmax, np.nanmax(filled_data)) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=2, symmetric_cbar=False, kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, np.nanmin(filled_data)) assert_equal(cbar_vmax, np.nanmax(filled_data)) # symmetric_cbar is set to 'auto', same behaviours as True for this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=None, symmetric_cbar='auto', kwargs=kwargs) assert_equal(vmin, -np.nanmax(filled_data)) assert_equal(vmax, np.nanmax(filled_data)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=2, symmetric_cbar='auto', kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None)
def test_get_colorbar_and_data_ranges_masked_array(): # data with positive and negative range affine = np.eye(4) data = np.array([[-0.5, 1.0, np.nan], [0.0, np.nan, -0.2], [1.5, 2.5, 3.0]]) masked_data = np.ma.masked_greater(data, 2.0) # Easier to fill masked values with NaN to test against later on filled_data = masked_data.filled(np.nan) img = nibabel.Nifti1Image(masked_data, affine) # Reasonable additional arguments that would end up being passed # to imshow in a real plotting use case kwargs = {"aspect": "auto", "alpha": 0.9} # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img, vmax=None, symmetric_cbar=True, kwargs=kwargs) assert_equal(vmin, -np.nanmax(filled_data)) assert_equal(vmax, np.nanmax(filled_data)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img, vmax=2, symmetric_cbar=True, kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=None, symmetric_cbar=False, kwargs=kwargs ) assert_equal(vmin, -np.nanmax(filled_data)) assert_equal(vmax, np.nanmax(filled_data)) assert_equal(cbar_vmin, np.nanmin(filled_data)) assert_equal(cbar_vmax, np.nanmax(filled_data)) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img, vmax=2, symmetric_cbar=False, kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, np.nanmin(filled_data)) assert_equal(cbar_vmax, np.nanmax(filled_data)) # symmetric_cbar is set to 'auto', same behaviours as True for this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=None, symmetric_cbar="auto", kwargs=kwargs ) assert_equal(vmin, -np.nanmax(filled_data)) assert_equal(vmax, np.nanmax(filled_data)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img, vmax=2, symmetric_cbar="auto", kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None)
def _colorbar_from_array(array, vmax, threshold, kwargs, cmap='cold_hot'): """Generate a custom colorbar for an array. Internal function used by plot_img_on_surf array : np.ndarray Any 3D array. vmax : float upper bound for plotting of stat_map values. threshold : float If None is given, the colorbar is not thresholded. If a number is given, it is used to threshold the colorbar. Absolute values lower than threshold are shown in gray. kwargs : dict Extra arguments passed to _get_colorbar_and_data_ranges. cmap : str, optional The name of a matplotlib or nilearn colormap. Default='cold_hot'. """ cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( array, vmax, True, kwargs ) norm = Normalize(vmin=vmin, vmax=vmax) cmaplist = [cmap(i) for i in range(cmap.N)] if threshold is None: threshold = 0. # set colors to grey for absolute values < threshold istart = int(norm(-threshold, clip=True) * (cmap.N - 1)) istop = int(norm(threshold, clip=True) * (cmap.N - 1)) for i in range(istart, istop): cmaplist[i] = (0.5, 0.5, 0.5, 1.) our_cmap = LinearSegmentedColormap.from_list('Custom cmap', cmaplist, cmap.N) sm = plt.cm.ScalarMappable(cmap=our_cmap, norm=plt.Normalize(vmin=vmin, vmax=vmax)) # fake up the array of the scalar mappable. sm._A = [] return sm
def test_get_colorbar_and_data_ranges_pos_neg(): # data with positive and negative range data = np.array([[-.5, 1., np.nan], [0., np.nan, -.2], [1.5, 2.5, 3.]]) # Reasonable additional arguments that would end up being passed # to imshow in a real plotting use case kwargs = {'aspect': 'auto', 'alpha': 0.9} # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax=None, symmetric_cbar=True, kwargs=kwargs) assert vmin == -np.nanmax(data) assert vmax == np.nanmax(data) assert cbar_vmin == None assert cbar_vmax == None # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax=2, symmetric_cbar=True, kwargs=kwargs) assert vmin == -2 assert vmax == 2 assert cbar_vmin == None assert cbar_vmax == None # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax=None, symmetric_cbar=False, kwargs=kwargs) assert vmin == -np.nanmax(data) assert vmax == np.nanmax(data) assert cbar_vmin == np.nanmin(data) assert cbar_vmax == np.nanmax(data) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax=2, symmetric_cbar=False, kwargs=kwargs) assert vmin == -2 assert vmax == 2 assert cbar_vmin == np.nanmin(data) assert cbar_vmax == np.nanmax(data) # symmetric_cbar is set to 'auto', same behaviours as True for this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax=None, symmetric_cbar='auto', kwargs=kwargs) assert vmin == -np.nanmax(data) assert vmax == np.nanmax(data) assert cbar_vmin == None assert cbar_vmax == None # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax=2, symmetric_cbar='auto', kwargs=kwargs) assert vmin == -2 assert vmax == 2 assert cbar_vmin == None assert cbar_vmax == None
def test_get_colorbar_and_data_ranges_pos(): # data with positive range affine = np.eye(4) data_pos = np.array([[0, 1., np.nan], [0., np.nan, 0], [1.5, 2.5, 3.]]) img_pos = nibabel.Nifti1Image(data_pos, affine) # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_pos, vmax=None, symmetric_cbar=True, kwargs={}) assert_equal(vmin, -np.nanmax(data_pos)) assert_equal(vmax, np.nanmax(data_pos)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_pos, vmax=2, symmetric_cbar=True, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_pos, vmax=None, symmetric_cbar=False, kwargs={}) assert_equal(vmin, -np.nanmax(data_pos)) assert_equal(vmax, np.nanmax(data_pos)) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_pos, vmax=2, symmetric_cbar=False, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None) # symmetric_cbar is set to 'auto', same behaviour as false in this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_pos, vmax=None, symmetric_cbar='auto', kwargs={}) assert_equal(vmin, -np.nanmax(data_pos)) assert_equal(vmax, np.nanmax(data_pos)) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_pos, vmax=2, symmetric_cbar='auto', kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None)
def test_get_colorbar_and_data_ranges_neg(): # data with negative range affine = np.eye(4) data_neg = np.array([[-.5, 0, np.nan], [0., np.nan, -.2], [0, 0, 0]]) img_neg = nibabel.Nifti1Image(data_neg, affine) # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_neg, vmax=None, symmetric_cbar=True, kwargs={}) assert_equal(vmin, np.nanmin(data_neg)) assert_equal(vmax, -np.nanmin(data_neg)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_neg, vmax=2, symmetric_cbar=True, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_neg, vmax=None, symmetric_cbar=False, kwargs={}) assert_equal(vmin, np.nanmin(data_neg)) assert_equal(vmax, -np.nanmin(data_neg)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_neg, vmax=2, symmetric_cbar=False, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0) # symmetric_cbar is set to 'auto', same behaviour as False in this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_neg, vmax=None, symmetric_cbar='auto', kwargs={}) assert_equal(vmin, np.nanmin(data_neg)) assert_equal(vmax, -np.nanmin(data_neg)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_neg, vmax=2, symmetric_cbar='auto', kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0)
def test_get_colorbar_and_data_ranges_pos(): # data with positive range affine = np.eye(4) data_pos = np.array([[0, 1.0, np.nan], [0.0, np.nan, 0], [1.5, 2.5, 3.0]]) img_pos = nibabel.Nifti1Image(data_pos, affine) # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img_pos, vmax=None, symmetric_cbar=True, kwargs={}) assert_equal(vmin, -np.nanmax(data_pos)) assert_equal(vmax, np.nanmax(data_pos)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img_pos, vmax=2, symmetric_cbar=True, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_pos, vmax=None, symmetric_cbar=False, kwargs={} ) assert_equal(vmin, -np.nanmax(data_pos)) assert_equal(vmax, np.nanmax(data_pos)) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img_pos, vmax=2, symmetric_cbar=False, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None) # symmetric_cbar is set to 'auto', same behaviour as false in this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_pos, vmax=None, symmetric_cbar="auto", kwargs={} ) assert_equal(vmin, -np.nanmax(data_pos)) assert_equal(vmax, np.nanmax(data_pos)) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img_pos, vmax=2, symmetric_cbar="auto", kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None)
def test_get_colorbar_and_data_ranges_pos(): # data with positive range data_pos = np.array([[0, 1., np.nan], [0., np.nan, 0], [1.5, 2.5, 3.]]) # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=None, symmetric_cbar=True, kwargs={}) assert vmin == -np.nanmax(data_pos) assert vmax == np.nanmax(data_pos) assert cbar_vmin == None assert cbar_vmax == None # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=2, symmetric_cbar=True, kwargs={}) assert vmin == -2 assert vmax == 2 assert cbar_vmin == None assert cbar_vmax == None # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=None, symmetric_cbar=False, kwargs={}) assert vmin == -np.nanmax(data_pos) assert vmax == np.nanmax(data_pos) assert cbar_vmin == 0 assert cbar_vmax == None # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=2, symmetric_cbar=False, kwargs={}) assert vmin == -2 assert vmax == 2 assert cbar_vmin == 0 assert cbar_vmax == None # symmetric_cbar is set to 'auto', same behaviour as false in this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=None, symmetric_cbar='auto', kwargs={}) assert vmin == -np.nanmax(data_pos) assert vmax == np.nanmax(data_pos) assert cbar_vmin == 0 assert cbar_vmax == None # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=2, symmetric_cbar='auto', kwargs={}) assert vmin == -2 assert vmax == 2 assert cbar_vmin == 0 assert cbar_vmax == None
def test_get_colorbar_and_data_ranges_neg(): # data with negative range data_neg = np.array([[-.5, 0, np.nan], [0., np.nan, -.2], [0, 0, 0]]) # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=None, symmetric_cbar=True, kwargs={}) assert vmin == np.nanmin(data_neg) assert vmax == -np.nanmin(data_neg) assert cbar_vmin == None assert cbar_vmax == None # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=2, symmetric_cbar=True, kwargs={}) assert vmin == -2 assert vmax == 2 assert cbar_vmin == None assert cbar_vmax == None # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=None, symmetric_cbar=False, kwargs={}) assert vmin == np.nanmin(data_neg) assert vmax == -np.nanmin(data_neg) assert cbar_vmin == None assert cbar_vmax == 0 # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=2, symmetric_cbar=False, kwargs={}) assert vmin == -2 assert vmax == 2 assert cbar_vmin == None assert cbar_vmax == 0 # symmetric_cbar is set to 'auto', same behaviour as False in this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=None, symmetric_cbar='auto', kwargs={}) assert vmin == np.nanmin(data_neg) assert vmax == -np.nanmin(data_neg) assert cbar_vmin == None assert cbar_vmax == 0 # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=2, symmetric_cbar='auto', kwargs={}) assert vmin == -2 assert vmax == 2 assert cbar_vmin == None assert cbar_vmax == 0
def test_get_colorbar_and_data_ranges_neg(): # data with negative range affine = np.eye(4) data_neg = np.array([[-0.5, 0, np.nan], [0.0, np.nan, -0.2], [0, 0, 0]]) img_neg = nibabel.Nifti1Image(data_neg, affine) # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img_neg, vmax=None, symmetric_cbar=True, kwargs={}) assert_equal(vmin, np.nanmin(data_neg)) assert_equal(vmax, -np.nanmin(data_neg)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img_neg, vmax=2, symmetric_cbar=True, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_neg, vmax=None, symmetric_cbar=False, kwargs={} ) assert_equal(vmin, np.nanmin(data_neg)) assert_equal(vmax, -np.nanmin(data_neg)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img_neg, vmax=2, symmetric_cbar=False, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0) # symmetric_cbar is set to 'auto', same behaviour as False in this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img_neg, vmax=None, symmetric_cbar="auto", kwargs={} ) assert_equal(vmin, np.nanmin(data_neg)) assert_equal(vmax, -np.nanmin(data_neg)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(img_neg, vmax=2, symmetric_cbar="auto", kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0)
def __init__(self, ndvar, cmap=None, vmin=None, vmax=None, dest='mri', mri_resolution=False, mni305=None, black_bg=False, display_mode=None, threshold=None, colorbar=False, draw_cross=True, annotate=True, alpha=0.7, plot_abs=False, draw_arrows=True, symmetric_cbar='auto', interpolation='nearest', show_time=False, **kwargs): # Give wxPython a chance to initialize the menu before pyplot if not use_inline_backend(): from .._wxgui import get_app get_app(jumpstart=True) # nilearn imports matplotlib.pyplot and messes with the backend unless # DISPLAY is set old_display = os.environ.get('DISPLAY') if old_display is None: os.environ['DISPLAY'] = 'duh' from nilearn.image import index_img from nilearn.plotting.displays import get_projector from nilearn.plotting.img_plotting import _get_colorbar_and_data_ranges if old_display is None: del os.environ['DISPLAY'] # check parameters if vmax is not None and np.isnan(vmax): raise ValueError( f"vmax={vmax!r} (Tip: Use np.nanmax() instead of np.max())") elif vmin is not None and np.isnan(vmin): raise ValueError( f"vmin={vmin!r} (Tip: Use np.nanmin() instead of np.min())") if isinstance(ndvar, VolumeSourceSpace): source = ndvar ndvar = time = None else: ndvar = brain_data(ndvar) source = ndvar.get_dim('source') if not isinstance(source, VolumeSourceSpace): raise ValueError( f"ndvar={ndvar!r}: need volume source space data") time = ndvar.get_dim('time') if ndvar.has_dim('time') else None if isinstance(ndvar.x, np.ma.MaskedArray) and np.all(ndvar.x.mask): ndvar = None if mni305 is None: mni305 = source.subject == 'fsaverage' if ndvar is None: cbar_vmin = cbar_vmax = imgs = img0 = dir_imgs = threshold = None else: if ndvar.has_case: ndvar = ndvar.mean('case') src = source.get_source_space() img = _stc_to_volume(ndvar, src, dest, mri_resolution, mni305) if time is not None: imgs = [index_img(img, i) for i in range(len(time))] img0 = imgs[0] else: img0 = img imgs = None if draw_arrows: if not ndvar.has_dim('space'): draw_arrows = False dir_imgs = None else: dir_imgs = [] for direction in ndvar.space._directions: dir_img = _stc_to_volume(ndvar.sub(space=direction), src, dest, mri_resolution, mni305) if ndvar.has_dim('time'): dir_imgs.append([ index_img(dir_img, i) for i in range(len(ndvar.time)) ]) else: dir_imgs.append([dir_img]) if plot_abs: raise ValueError( f"Cannot use plot_abs={plot_abs} with draw_arrows={draw_arrows}" ) else: dir_imgs = None # determine parameters for colorbar if ndvar.has_dim('space'): data = ndvar.norm('space').x else: data = ndvar.x if cmap is None: if data.dtype.kind == 'b': cmap = 'copper' if black_bg else 'Oranges' else: cmap = 'cold_hot' if black_bg else 'cold_white_hot' if data.dtype.kind == 'b': if vmax is None: vmax = 1 if vmin is None: vmin = 0 cbar_vmin = cbar_vmax = None elif plot_abs: cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax, symmetric_cbar, (), 0) else: cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax, symmetric_cbar, ()) # Deal with automatic settings of plot parameters if threshold == 'auto': # Threshold below a percentile value, to be sure that some # voxels pass the threshold threshold = _fast_abs_percentile(ndvar) if threshold is not None: threshold = float(threshold) if isinstance(ndvar.x, np.ma.MaskedArray): raise ValueError( f"Cannot use threshold={threshold} with masked data") self.time = time self._ndvar = ndvar self._imgs = imgs self._dir_imgs = dir_imgs # layout if display_mode is None: has_lh = 'lh' in source.hemi has_rh = 'rh' in source.hemi if has_rh != has_lh: display_mode = 'xz' else: display_mode = 'lyr' n_plots = 3 if display_mode == 'ortho' else len(display_mode) layout = Layout(n_plots, 0.85, 2.6, tight=False, ncol=n_plots, **kwargs) # frame title if layout.name: frame_title = layout.name elif isinstance(layout.title, str): frame_title = layout.title elif ndvar is not None and ndvar.name: frame_title = ndvar.name else: frame_title = source.subject EelFigure.__init__(self, frame_title, layout) project = get_projector(display_mode) display = project(img0, alpha=alpha, plot_abs=plot_abs, threshold=threshold, figure=self.figure, axes=None, black_bg=black_bg, colorbar=colorbar) if img0: display.add_overlay(img0, threshold=threshold, interpolation=interpolation, colorbar=colorbar, vmin=vmin, vmax=vmax, cmap=cmap) ColorBarMixin.__init__(self, self._colorbar_params, ndvar) self.display = display self.threshold = threshold self.interpolation = interpolation self.cmap = cmap self.colorbar = colorbar self.vmin = vmin self.vmax = vmax self._arrows = draw_arrows if draw_arrows: if img0: self.arrow_scale = 7 * np.max(np.abs([vmax, vmin])) self._add_arrows(0) if annotate: display.annotate() if draw_cross: display.draw_cross() if hasattr(display, '_cbar'): cbar = display._cbar _crop_colorbar(cbar, cbar_vmin, cbar_vmax) if show_time: color = 'w' if black_bg else 'k' time_text = self.figure.text(0, 1, '', va='top', c=color, zorder=1000) else: time_text = None TimeSlicerEF.__init__(self, 'time', time, display_text=time_text) self._show()
def get_stat_map(stat_map_img, bg_img, cut_coords=None, colorbar=True, title=None, threshold=None, annotate=True, draw_cross=True, black_bg='auto', cmap=cm.cold_hot, symmetric_cbar='auto', dim='auto', vmax=None, resampling_interpolation='continuous', n_colors=256, opacity=1, **kwargs): """ Intarctive viewer of a statistical map, with optional background Parameters ---------- stat_map_img : Niimg-like object See http://nilearn.github.io/manipulating_images/input_output.html The statistical map image. bg_img : Niimg-like object (default='MNI152') See http://nilearn.github.io/manipulating_images/input_output.html The background image that the stat map will be plotted on top of. If nothing is specified, the MNI152 template will be used. To turn off background image, just pass "bg_img=False". cut_coords : None, a tuple of floats, or an integer (default None) The MNI coordinates of the point where the cut is performed as a 3-tuple: (x, y, z). If None is given, the cuts is calculated automaticaly. This parameter is not currently supported. colorbar : boolean, optional (default True) If True, display a colorbar next to the plots. title : string or None (default=None) The title displayed on the figure (or None: no title). This parameter is not currently supported. threshold : str, number or None (default=None) If None is given, the image is not thresholded. If a number is given, it is used to threshold the image: values below the threshold (in absolute value) are plotted as transparent. If auto is given, the threshold is determined magically by analysis of the image. annotate : boolean (default=True) If annotate is True, positions and left/right annotation are added to the plot. draw_cross : boolean (default=True) If draw_cross is True, a cross is drawn on the plot to indicate the cut plosition. black_bg : boolean (default='auto') If True, the background of the image is set to be black. Otherwise, a white background is used. If set to auto, an educated guess is made to find if the background is white or black. cmap : matplotlib colormap, optional The colormap for specified image. The colormap *must* be symmetrical. symmetric_cbar : boolean or 'auto' (default='auto') Specifies whether the colorbar should range from -vmax to vmax or from vmin to vmax. Setting to 'auto' will select the latter if the range of the whole image is either positive or negative. Note: The colormap will always be set to range from -vmax to vmax. dim : float, 'auto' (default='auto') Dimming factor applied to background image. By default, automatic heuristics are applied based upon the background image intensity. Accepted float values, where a typical scan is between -2 and 2 (-2 = increase constrast; 2 = decrease contrast), but larger values can be used for a more pronounced effect. 0 means no dimming. vmax : float, or None (default=) max value for mapping colors. resampling_interpolation : string, optional (default nearest) The interpolation method for resampling See nilearn.image.resample_img n_colors : integer (default=256) The number of discrete colors to use in the colormap, if it is generated. opacity : float in [0,1] (default 1) The level of opacity of the overlay (0: transparent, 1: opaque) Returns ------- StatMapView : plot of the stat map. It can be saved as an html page or rendered (transparently) by the Jupyter notebook. """ # Load stat map stat_map_img = check_niimg_3d(stat_map_img, dtype='auto') _, _, vmin, vmax = _get_colorbar_and_data_ranges( _safe_get_data(stat_map_img, ensure_finite=True), vmax, symmetric_cbar, kwargs) # load background image, and resample stat map if bg_img is not None and bg_img is not False: bg_img, black_bg, bg_min, bg_max = _load_anat(bg_img, dim=dim, black_bg=black_bg) bg_img = _resample_to_self(bg_img, interpolation=resampling_interpolation) stat_map_img = image.resample_to_img( stat_map_img, bg_img, interpolation=resampling_interpolation) else: stat_map_img = _resample_to_self( stat_map_img, interpolation=resampling_interpolation) bg_img = image.new_img_like(stat_map_img, np.zeros(stat_map_img.shape), stat_map_img.affine) bg_min = 0 bg_max = 0 if black_bg == 'auto': black_bg = False # Select coordinates for the cut # https://github.com/nilearn/nilearn/blob/master/nilearn/plotting/displays.py#L943 if isinstance(cut_coords, numbers.Number): raise ValueError( "The input given for display_mode='ortho' needs to be " "a list of 3d world coordinates in (x, y, z). " "You provided single cut, cut_coords={0}".format(cut_coords)) if cut_coords is None: cut_coords = find_xyz_cut_coords(stat_map_img, activation_threshold=threshold) print(cut_coords) # Create a base64 sprite for the background bg_sprite = BytesIO() save_sprite(bg_img, output_sprite=bg_sprite, cmap='gray', format='jpg', resample=False, vmin=bg_min, vmax=bg_max) bg_sprite.seek(0) bg_base64 = encodebytes(bg_sprite.read()).decode('utf-8') bg_sprite.close() # Create a base64 sprite for the stat map # Possibly, also generate a file with the colormap stat_map_sprite = BytesIO() stat_map_json = StringIO() if colorbar: stat_map_cm = BytesIO() else: stat_map_cm = None cmap_c = _custom_cmap(cmap, vmin, vmax, threshold) save_sprite(stat_map_img, stat_map_sprite, stat_map_cm, stat_map_json, vmax, vmin, cmap_c, threshold, n_colors, 'png', False) # Convert the sprite and colormap to base64 stat_map_sprite.seek(0) stat_map_base64 = encodebytes(stat_map_sprite.read()).decode('utf-8') stat_map_sprite.close() if colorbar: stat_map_cm.seek(0) cm_base64 = encodebytes(stat_map_cm.read()).decode('utf-8') stat_map_cm.close() else: cm_base64 = '' # Load the sprite meta-data from the json dump stat_map_json.seek(0) params = json.load(stat_map_json) stat_map_json.close() # Convet cut coordinates into cut slices cut_slices = np.round( nb.affines.apply_affine(np.linalg.inv(stat_map_img.affine), cut_coords)) # Create a json-like structure # with all the brain sprite parameters sprite_params = { 'canvas': '3Dviewer', 'sprite': 'spriteImg', 'nbSlice': params['nbSlice'], 'overlay': { 'sprite': 'overlayImg', 'nbSlice': params['nbSlice'], 'opacity': opacity }, 'colorBackground': '#000000', 'colorFont': '#ffffff', 'colorCrosshair': '#de101d', 'crosshair': draw_cross, 'affine': params['affine'], 'flagCoordinates': annotate, 'title': title, 'flagValue': annotate, 'numSlice': { 'X': cut_slices[0], 'Y': cut_slices[1], 'Z': cut_slices[2] }, } if colorbar: sprite_params['colorMap'] = { 'img': 'colorMap', 'min': params['min'], 'max': params['max'] } return sprite_params, bg_base64, stat_map_base64, cm_base64
def test_get_colorbar_and_data_ranges_pos_neg(): # data with positive and negative range affine = np.eye(4) data = np.array([[-.5, 1., np.nan], [0., np.nan, -.2], [1.5, 2.5, 3.]]) img = nibabel.Nifti1Image(data, affine) # Reasonable additional arguments that would end up being passed # to imshow in a real plotting use case kwargs = {'aspect': 'auto', 'alpha': 0.9} # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=None, symmetric_cbar=True, kwargs=kwargs) assert_equal(vmin, -np.nanmax(data)) assert_equal(vmax, np.nanmax(data)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=2, symmetric_cbar=True, kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=None, symmetric_cbar=False, kwargs=kwargs) assert_equal(vmin, -np.nanmax(data)) assert_equal(vmax, np.nanmax(data)) assert_equal(cbar_vmin, np.nanmin(data)) assert_equal(cbar_vmax, np.nanmax(data)) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=2, symmetric_cbar=False, kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, np.nanmin(data)) assert_equal(cbar_vmax, np.nanmax(data)) # symmetric_cbar is set to 'auto', same behaviours as True for this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=None, symmetric_cbar='auto', kwargs=kwargs) assert_equal(vmin, -np.nanmax(data)) assert_equal(vmax, np.nanmax(data)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( img, vmax=2, symmetric_cbar='auto', kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None)
def _draw_colorbar(stat_map_img, axes, threshold=.1, nb_ticks=5, edge_color="0.5", edge_alpha=1, aspect=40, fraction=0.025, anchor=(10.0,0.5), cut_coords=None, positive_only=False, negative_only=False, cmap=None, ): if isinstance(stat_map_img, str): stat_map_img = path.abspath(path.expanduser(stat_map_img)) stat_map_img = nib.load(stat_map_img) stat_map_img_dat = _safe_get_data(stat_map_img, ensure_finite=True) if cmap: cmap = plt.cm.get_cmap(cmap) colors = cmap(np.linspace(0,1,256)) cmap_minus = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors[0:128,:]) cmap_plus = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors[128:255,:]) else: cmap_minus = MYMAP_MINUS cmap_plus = MYMAP_PLUS cmap = MYMAP cbar_vmin,cbar_vmax,vmin, vmax = _get_colorbar_and_data_ranges(stat_map_img_dat,None,"auto","") if cbar_vmin is not None or positive_only: vmin = 0 colmap = cmap_plus elif cbar_vmax is not None or negative_only: vmax = 0 colmap = cmap_minus else: colmap = cmap cbar_ax, p_ax = make_axes(axes, aspect=aspect, fraction=fraction, # pad=-0.5, anchor=anchor, # panchor=(-110.0, 0.5), ) ticks = np.linspace(vmin, vmax, nb_ticks) bounds = np.linspace(vmin, vmax, colmap.N) norm = mcolors.Normalize(vmin=vmin, vmax=vmax) # some colormap hacking cmaplist = [colmap(i) for i in range(colmap.N)] istart = int(norm(-threshold, clip=True) * (colmap.N - 1)) istop = int(norm(threshold, clip=True) * (colmap.N - 1)) for i in range(istart, (istop+1)): # just an average gray color cmaplist[i] = (0.5, 0.5, 0.5, 1.) our_cmap = colmap.from_list('Custom cmap', cmaplist, colmap.N) cbar = ColorbarBase( cbar_ax, ticks=ticks, norm=norm, orientation="vertical", cmap=our_cmap, boundaries=bounds, spacing="proportional", format="%.2g", ) cbar.outline.set_edgecolor(edge_color) cbar.outline.set_alpha(edge_alpha) cbar_ax.yaxis.tick_left() tick_color = 'k' for tick in cbar_ax.yaxis.get_ticklabels(): tick.set_color(tick_color) cbar_ax.yaxis.set_tick_params(width=0) return cbar_ax, p_ax,vmin,vmax,colmap
def get_params_for_grid_slice(vstc, vsrc, tstep, subjects_dir, cbar_range=None, **kwargs): """ Makes calculations that would be executed repeatedly every time a slice is computed and saves the results in a dictionary which is then read by plot_vstc_grid_slice(). Parameters: ----------- vstc : mne.VolSourceEstimate The volume source estimate. vsrc : mne.SourceSpaces The source space of the subject equivalent to the tstep : int Time step between successive samples in data. subjects_dir: Path to the subject directory. cbar_range : None, 2-tuple Color range of the plot. Returns: -------- params_plot_img_with_bg : dict Dictionary containing the parameters for plotting. """ img = vstc.as_volume(vsrc, dest='mri', mri_resolution=False) # TODO: why should vstc ever be 0? if vstc == 0: # TODO: how would _make_image work if vstc is zero anyways? if tstep is not None: img = _make_image(vstc, vsrc, tstep, dest='mri', mri_resolution=False) else: print(' Please provide the tstep value !') subject = vsrc[0]['subject_his_id'] temp_t1_fname = op.join(subjects_dir, subject, 'mri', 'T1.mgz') bg_img = temp_t1_fname dim = 'auto' black_bg = 'auto' vmax = None symmetric_cbar = False from nilearn.plotting.img_plotting import _load_anat, _get_colorbar_and_data_ranges from nilearn._utils import check_niimg_4d from nilearn._utils.niimg_conversions import _safe_get_data bg_img, black_bg, bg_vmin, bg_vmax = _load_anat(bg_img, dim=dim, black_bg=black_bg) stat_map_img = check_niimg_4d(img, dtype='auto') cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( _safe_get_data(stat_map_img, ensure_finite=True), vmax, symmetric_cbar, kwargs) if cbar_range is not None: cbar_vmin = cbar_range[0] cbar_vmax = cbar_range[1] vmin = cbar_range[0] vmax = cbar_range[1] params_plot_img_with_bg = dict() params_plot_img_with_bg['bg_img'] = bg_img params_plot_img_with_bg['black_bg'] = black_bg params_plot_img_with_bg['bg_vmin'] = bg_vmin params_plot_img_with_bg['bg_vmax'] = bg_vmax params_plot_img_with_bg['stat_map_img'] = stat_map_img params_plot_img_with_bg['cbar_vmin'] = cbar_vmin params_plot_img_with_bg['cbar_vmax'] = cbar_vmax params_plot_img_with_bg['vmin'] = vmin params_plot_img_with_bg['vmax'] = vmax return params_plot_img_with_bg
def __init__(self, ndvar, cmap=None, vmin=None, vmax=None, dest='mri', mri_resolution=False, mni305=None, black_bg=False, display_mode=None, threshold=None, colorbar=False, draw_cross=True, annotate=True, alpha=0.7, plot_abs=False, draw_arrows=True, symmetric_cbar='auto', interpolation='nearest', **kwargs): # Give wxPython a chance to initialize the menu before pyplot from .._wxgui import get_app get_app(jumpstart=True) # Lazy import of matplotlib.pyplot from nilearn.image import index_img from nilearn.plotting import cm from nilearn.plotting.displays import get_projector from nilearn.plotting.img_plotting import _get_colorbar_and_data_ranges # check parameters if vmax is not None and np.isnan(vmax): raise ValueError( f"vmax={vmax!r} (Tip: Use np.nanmax() instead of np.max())") elif vmin is not None and np.isnan(vmin): raise ValueError( f"vmin={vmin!r} (Tip: Use np.nanmin() instead of np.min())") if isinstance(ndvar, VolumeSourceSpace): source = ndvar ndvar = time = None else: ndvar = brain_data(ndvar) source = ndvar.get_dim('source') if not isinstance(source, VolumeSourceSpace): raise ValueError( f"ndvar={ndvar!r}: need volume source space data") time = ndvar.get_dim('time') if ndvar.has_dim('time') else None if isinstance(ndvar.x, np.ma.MaskedArray) and np.all(ndvar.x.mask): ndvar = None if mni305 is None: mni305 = source.subject == 'fsaverage' if ndvar: if ndvar.has_case: ndvar = ndvar.mean('case') src = source.get_source_space() img = _stc_to_volume(ndvar, src, dest, mri_resolution, mni305) if time is not None: t0 = time[0] imgs = [index_img(img, i) for i in range(len(time))] img0 = imgs[0] else: img0 = img imgs = t0 = None if draw_arrows: if not ndvar.has_dim('space'): draw_arrows = False dir_imgs = None else: dir_imgs = [] for direction in ndvar.space._directions: dir_img = _stc_to_volume(ndvar.sub(space=direction), src, dest, mri_resolution, mni305) if ndvar.has_dim('time'): dir_imgs.append([ index_img(dir_img, i) for i in range(len(ndvar.time)) ]) else: dir_imgs.append([dir_img]) if plot_abs: raise ValueError( f"Cannot use plot_abs={plot_abs} with draw_arrows={draw_arrows}" ) else: dir_imgs = None # determine parameters for colorbar if ndvar.has_dim('space'): data = ndvar.norm('space').x else: data = ndvar.x if cmap is None: if data.dtype.kind == 'b': cmap = 'copper' if black_bg else 'Oranges' else: cmap = cm.cold_hot if black_bg else cm.cold_white_hot if data.dtype.kind == 'b': if vmax is None: vmax = 1 if vmin is None: vmin = 0 cbar_vmin = cbar_vmax = None elif plot_abs: cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax, symmetric_cbar, kwargs, 0) else: cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax, symmetric_cbar, kwargs) # Deal with automatic settings of plot parameters if threshold == 'auto': # Threshold below a percentile value, to be sure that some # voxels pass the threshold threshold = _fast_abs_percentile(ndvar) if threshold is not None: threshold = float(threshold) if isinstance(ndvar.x, np.ma.MaskedArray): raise ValueError( f"Cannot use threshold={threshold} with masked data") # If ```threshold = None``` and using diverging colormaps, 0.5 may not corresponds to pure white/ black. # This issue is more prominent in Apple’s color management than Windows/ Linux counterpart. if symmetric_cbar and (threshold is None): subthreshold = (0, 0, 0) if black_bg else (1.0, 1.0, 1.0) cmap = soft_threshold_colormap(cmap, threshold=vmax / cmap.N, vmax=vmax, subthreshold=subthreshold, symmetric=True) else: cbar_vmin = cbar_vmax = imgs = img0 = dir_imgs = t0 = threshold = None self.time = time self._ndvar = ndvar self._imgs = imgs self._dir_imgs = dir_imgs # layout if display_mode is None: has_lh = 'lh' in source.hemi has_rh = 'rh' in source.hemi if has_rh != has_lh: display_mode = 'xz' else: display_mode = 'lyr' n_plots = 3 if display_mode == 'ortho' else len(display_mode) layout = Layout(n_plots, 0.85, 2.6, tight=False, ncol=n_plots, **kwargs) # frame title if layout.name: frame_title = layout.name elif isinstance(layout.title, str): frame_title = layout.title elif ndvar and ndvar.name: frame_title = ndvar.name else: frame_title = source.subject EelFigure.__init__(self, frame_title, layout) project = get_projector(display_mode) display = project(img0, alpha=alpha, plot_abs=plot_abs, threshold=threshold, figure=self.figure, axes=None, black_bg=black_bg, colorbar=colorbar) if img0: display.add_overlay(img0, threshold=threshold, interpolation=interpolation, colorbar=colorbar, vmin=vmin, vmax=vmax, cmap=cmap) ColorBarMixin.__init__(self, self._colorbar_params, ndvar) self.display = display self.threshold = threshold self.interpolation = interpolation self.cmap = cmap self.colorbar = colorbar self.vmin = vmin self.vmax = vmax self._arrows = draw_arrows if draw_arrows: if img0: self.arrow_scale = 7 * np.max(np.abs([vmax, vmin])) self._add_arrows(0) if annotate: display.annotate() if draw_cross: display.draw_cross() if layout.title is True: if t0 is None: raise TypeError( f"title=True; only allowed when displaying data with multiple time points" ) display.title("???") self._update_title(t0) elif layout.title: display.title(layout.title) if hasattr(display, '_cbar'): cbar = display._cbar _crop_colorbar(cbar, cbar_vmin, cbar_vmax) TimeSlicerEF.__init__(self, 'time', time) self._show()
expected = { "pos_neg": _expected_results_pos_neg, "pos": _expected_results_pos, "neg": _expected_results_neg, "masked": _expected_results_pos_neg } return expected[case](symmetric_cbar, vmax, data) @pytest.mark.parametrize("case,data", [("pos_neg", data_pos_neg), ("pos", data_pos), ("neg", data_neg), ("masked", data_masked)]) @pytest.mark.parametrize("symmetric_cbar", [True, False, 'auto']) @pytest.mark.parametrize("vmax", [None, 2]) def test_get_colorbar_and_data_ranges(case, data, symmetric_cbar, vmax, expected_results): """Tests for _get_colorbar_and_data_ranges. Tests values of `vmin`, `vmax`, `cbar_vmin`, and `cbar_vmax` with: - data having both positive and negatives values. - data having only negative values. - data having only positive values. - masked data. """ kwargs = {'aspect': 'auto', 'alpha': 0.9} assert (_get_colorbar_and_data_ranges(data, vmax=vmax, symmetric_cbar=symmetric_cbar, kwargs=kwargs) == expected_results)
def test_get_colorbar_and_data_ranges_neg(): # data with negative range data_neg = np.array([[-.5, 0, np.nan], [0., np.nan, -.2], [0, 0, 0]]) # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=None, symmetric_cbar=True, kwargs={}) assert_equal(vmin, np.nanmin(data_neg)) assert_equal(vmax, -np.nanmin(data_neg)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=2, symmetric_cbar=True, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=None, symmetric_cbar=False, kwargs={}) assert_equal(vmin, np.nanmin(data_neg)) assert_equal(vmax, -np.nanmin(data_neg)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=2, symmetric_cbar=False, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0) # symmetric_cbar is set to 'auto', same behaviour as False in this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=None, symmetric_cbar='auto', kwargs={}) assert_equal(vmin, np.nanmin(data_neg)) assert_equal(vmax, -np.nanmin(data_neg)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_neg, vmax=2, symmetric_cbar='auto', kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, 0)
def __init__(self, ndvar, cmap=None, vmin=None, vmax=None, dest='mri', mri_resolution=False, mni305=None, black_bg=False, display_mode=None, threshold=None, colorbar=False, draw_cross=True, annotate=True, alpha=0.7, plot_abs=False, draw_arrows=True, symmetric_cbar='auto', interpolation='nearest', **kwargs): # Give wxPython a chance to initialize the menu before pyplot from .._wxgui import get_app get_app(jumpstart=True) # Lazy import of matplotlib.pyplot from nilearn.image import index_img from nilearn.plotting import cm from nilearn.plotting.displays import get_projector from nilearn.plotting.img_plotting import _get_colorbar_and_data_ranges # check parameters if vmax is not None and np.isnan(vmax): raise ValueError(f"vmax={vmax!r} (Tip: Use np.nanmax() instead of np.max())") elif vmin is not None and np.isnan(vmin): raise ValueError(f"vmin={vmin!r} (Tip: Use np.nanmin() instead of np.min())") if isinstance(ndvar, VolumeSourceSpace): source = ndvar ndvar = time = None else: ndvar = brain_data(ndvar) source = ndvar.get_dim('source') if not isinstance(source, VolumeSourceSpace): raise ValueError(f"ndvar={ndvar!r}: need volume source space data") time = ndvar.get_dim('time') if ndvar.has_dim('time') else None if isinstance(ndvar.x, np.ma.MaskedArray) and np.all(ndvar.x.mask): ndvar = None if mni305 is None: mni305 = source.subject == 'fsaverage' if ndvar: if ndvar.has_case: ndvar = ndvar.mean('case') src = source.get_source_space() img = _stc_to_volume(ndvar, src, dest, mri_resolution, mni305) if time is not None: t0 = time[0] imgs = [index_img(img, i) for i in range(len(time))] img0 = imgs[0] else: img0 = img imgs = t0 = None if draw_arrows: if not ndvar.has_dim('space'): draw_arrows = False dir_imgs = None else: dir_imgs = [] for direction in ndvar.space._directions: dir_img = _stc_to_volume(ndvar.sub(space=direction), src, dest, mri_resolution, mni305) if ndvar.has_dim('time'): dir_imgs.append([index_img(dir_img, i) for i in range(len(ndvar.time))]) else: dir_imgs.append([dir_img]) if plot_abs: raise ValueError(f"Cannot use plot_abs={plot_abs} with draw_arrows={draw_arrows}") else: dir_imgs = None # determine parameters for colorbar if ndvar.has_dim('space'): data = ndvar.norm('space').x else: data = ndvar.x if cmap is None: if data.dtype.kind == 'b': cmap = 'copper' if black_bg else 'Oranges' else: cmap = cm.cold_hot if black_bg else cm.cold_white_hot if data.dtype.kind == 'b': if vmax is None: vmax = 1 if vmin is None: vmin = 0 cbar_vmin = cbar_vmax = None elif plot_abs: cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax, symmetric_cbar, kwargs, 0) else: cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data, vmax, symmetric_cbar, kwargs) # Deal with automatic settings of plot parameters if threshold == 'auto': # Threshold below a percentile value, to be sure that some # voxels pass the threshold threshold = _fast_abs_percentile(ndvar) if threshold is not None: threshold = float(threshold) if isinstance(ndvar.x, np.ma.MaskedArray): raise ValueError(f"Cannot use threshold={threshold} with masked data") else: cbar_vmin = cbar_vmax = imgs = img0 = dir_imgs = t0 = threshold = None self.time = time self._ndvar = ndvar self._imgs = imgs self._dir_imgs = dir_imgs # layout if display_mode is None: has_lh = 'lh' in source.hemi has_rh = 'rh' in source.hemi if has_rh != has_lh: display_mode = 'xz' else: display_mode = 'lyr' n_plots = 3 if display_mode == 'ortho' else len(display_mode) layout = Layout(n_plots, 0.85, 2.6, tight=False, ncol=n_plots, **kwargs) # frame title if layout.name: frame_title = layout.name elif isinstance(layout.title, str): frame_title = layout.title elif ndvar and ndvar.name: frame_title = ndvar.name else: frame_title = source.subject EelFigure.__init__(self, frame_title, layout) project = get_projector(display_mode) display = project(img0, alpha=alpha, plot_abs=plot_abs, threshold=threshold, figure=self.figure, axes=None, black_bg=black_bg, colorbar=colorbar) if img0: display.add_overlay(img0, threshold=threshold, interpolation=interpolation, colorbar=colorbar, vmin=vmin, vmax=vmax, cmap=cmap) ColorBarMixin.__init__(self, self._colorbar_params, ndvar) self.display = display self.threshold = threshold self.interpolation = interpolation self.cmap = cmap self.colorbar = colorbar self.vmin = vmin self.vmax = vmax self._arrows = draw_arrows if draw_arrows: if img0: self.arrow_scale = 7 * np.max(np.abs([vmax, vmin])) self._add_arrows(0) if annotate: display.annotate() if draw_cross: display.draw_cross() if layout.title is True: if t0 is None: raise TypeError(f"title=True; only allowed when displaying data with multiple time points") display.title("???") self._update_title(t0) elif layout.title: display.title(layout.title) if hasattr(display, '_cbar'): cbar = display._cbar _crop_colorbar(cbar, cbar_vmin, cbar_vmax) TimeSlicerEF.__init__(self, 'time', time) self._show()
def plot_surf_stat_map(surf_mesh, stat_map, bg_map=None, hemi='left', view='lateral', threshold=None, alpha='auto', vmax=None, cmap='cold_hot', colorbar=True, symmetric_cbar="auto", bg_on_data=False, darkness=1, title=None, output_file=None, axes=None, figure=None, **kwargs): """Plotting a stats map on a surface mesh with optional background .. versionadded:: 0.3 Parameters ---------- surf_mesh : str or list of two numpy.ndarray Surface mesh geometry, can be a file (valid formats are .gii or Freesurfer specific files such as .orig, .pial, .sphere, .white, .inflated) or a list of two Numpy arrays, the first containing the x-y-z coordinates of the mesh vertices, the second containing the indices (into coords) of the mesh faces stat_map : str or numpy.ndarray Statistical map to be displayed on the surface mesh, can be a file (valid formats are .gii, .mgz, .nii, .nii.gz, or Freesurfer specific files such as .thickness, .curv, .sulc, .annot, .label) or a Numpy array with a value for each vertex of the surf_mesh. bg_map : Surface data object (to be defined), optional Background image to be plotted on the mesh underneath the stat_map in greyscale, most likely a sulcal depth map for realistic shading. hemi : {'left', 'right'}, optional Hemispere to display. Default='left'. view : {'lateral', 'medial', 'dorsal', 'ventral', 'anterior', 'posterior'}, optional View of the surface that is rendered. Default='lateral'. threshold : a number or None, optional If None is given, the image is not thresholded. If a number is given, it is used to threshold the image, values below the threshold (in absolute value) are plotted as transparent. cmap : matplotlib colormap in str or colormap object, optional To use for plotting of the stat_map. Either a string which is a name of a matplotlib colormap, or a matplotlib colormap object. Default='cold_hot'. colorbar : bool, optional If True, a symmetric colorbar of the statistical map is displayed. Default=True. alpha : float or 'auto', optional Alpha level of the mesh (not the stat_map). If 'auto' is chosen, alpha will default to .5 when no bg_map is passed and to 1 if a bg_map is passed. Default='auto'. vmax : float, optional Upper bound for plotting of stat_map values. symmetric_cbar : bool or 'auto', optional Specifies whether the colorbar should range from -vmax to vmax or from vmin to vmax. Setting to 'auto' will select the latter if the range of the whole image is either positive or negative. Note: The colormap will always range from -vmax to vmax. Default='auto'. bg_on_data : bool, optional If True, and a bg_map is specified, the stat_map data is multiplied by the background image, so that e.g. sulcal depth is visible beneath the stat_map. NOTE: that this non-uniformly changes the stat_map values according to e.g the sulcal depth. Default=False. darkness : float between 0 and 1, optional Specifying the darkness of the background image. 1 indicates that the original values of the background are used. .5 indicates the background values are reduced by half before being applied. Default=1. title : str, optional Figure title. output_file : str, optional The name of an image file to export plot to. Valid extensions are .png, .pdf, .svg. If output_file is not None, the plot is saved to a file, and the display is closed. axes : instance of matplotlib axes, None, optional The axes instance to plot to. The projection must be '3d' (e.g., `figure, axes = plt.subplots(subplot_kw={'projection': '3d'})`, where axes should be passed.). If None, a new axes is created. figure : instance of matplotlib figure, None, optional The figure instance to plot to. If None, a new figure is created. See Also -------- nilearn.datasets.fetch_surf_fsaverage: For surface data object to be used as background map for this plotting function. nilearn.plotting.plot_surf: For brain surface visualization. """ loaded_stat_map = load_surf_data(stat_map) # Call _get_colorbar_and_data_ranges to derive symmetric vmin, vmax # And colorbar limits depending on symmetric_cbar settings cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( loaded_stat_map, vmax, symmetric_cbar, kwargs) display = plot_surf(surf_mesh, surf_map=loaded_stat_map, bg_map=bg_map, hemi=hemi, view=view, avg_method='mean', threshold=threshold, cmap=cmap, colorbar=colorbar, alpha=alpha, bg_on_data=bg_on_data, darkness=darkness, vmax=vmax, vmin=vmin, title=title, output_file=output_file, axes=axes, figure=figure, cbar_vmin=cbar_vmin, cbar_vmax=cbar_vmax, **kwargs) return display
def plot_surf_stat_map(surf_mesh, stat_map, bg_map=None, hemi='left', view='lateral', engine='matplotlib', threshold=None, alpha='auto', vmax=None, cmap='cold_hot', colorbar=True, symmetric_cbar="auto", cbar_tick_format="auto", bg_on_data=False, darkness=1, title=None, title_font_size=18, output_file=None, axes=None, figure=None, **kwargs): """Plotting a stats map on a surface mesh with optional background .. versionadded:: 0.3 Parameters ---------- surf_mesh : str or list of two numpy.ndarray or Mesh Surface mesh geometry, can be a file (valid formats are .gii or Freesurfer specific files such as .orig, .pial, .sphere, .white, .inflated) or a list of two Numpy arrays, the first containing the x-y-z coordinates of the mesh vertices, the second containing the indices (into coords) of the mesh faces, or a Mesh object with "coordinates" and "faces" attributes. stat_map : str or numpy.ndarray Statistical map to be displayed on the surface mesh, can be a file (valid formats are .gii, .mgz, .nii, .nii.gz, or Freesurfer specific files such as .thickness, .area, .curv, .sulc, .annot, .label) or a Numpy array with a value for each vertex of the surf_mesh. bg_map : Surface data object (to be defined), optional Background image to be plotted on the mesh underneath the stat_map in greyscale, most likely a sulcal depth map for realistic shading. %(hemi)s %(view)s engine : {'matplotlib', 'plotly'}, optional .. versionadded:: 0.8.2 Selects which plotting engine will be used by ``plot_surf_stat_map``. Currently, only ``matplotlib`` and ``plotly`` are supported. .. note:: To use the ``plotly`` engine you need to have ``plotly`` installed. .. note:: To be able to save figures to disk with the ``plotly`` engine you need to have ``kaleido`` installed. .. warning:: The ``plotly`` engine is new and experimental. Please report bugs that you may encounter. Default='matplotlib'. threshold : a number or None, optional If None is given, the image is not thresholded. If a number is given, it is used to threshold the image, values below the threshold (in absolute value) are plotted as transparent. %(cmap)s %(cbar_tick_format)s Default="auto" which will select: - '%%.2g' (scientific notation) with ``matplotlib`` engine. - '.1f' (rounded floats) with ``plotly`` engine. .. versionadded:: 0.7.1 %(colorbar)s .. note:: This function uses a symmetric colorbar for the statistical map. Default=True. alpha : float or 'auto', optional Alpha level of the mesh (not the stat_map). If 'auto' is chosen, alpha will default to .5 when no bg_map is passed and to 1 if a bg_map is passed. Default='auto'. .. note:: This option is currently only implemented for the ``matplotlib`` engine. %(vmax)s %(symmetric_cbar)s Default='auto'. %(bg_on_data)s Default=False. %(darkness)s Default=1. .. note:: This option is currently only implemented for the ``matplotlib`` engine. %(title)s title_font_size : :obj:`int`, optional Size of the title font. .. versionadded:: 0.8.2 Default=18. %(output_file)s axes : instance of matplotlib axes, None, optional The axes instance to plot to. The projection must be '3d' (e.g., `figure, axes = plt.subplots(subplot_kw={'projection': '3d'})`, where axes should be passed.). If None, a new axes is created. .. note:: This option is currently only implemented for the ``matplotlib`` engine. %(figure)s .. note:: This option is currently only implemented for the ``matplotlib`` engine. kwargs : dict, optional Keyword arguments passed to :func:`nilearn.plotting.plot_surf`. See Also -------- nilearn.datasets.fetch_surf_fsaverage: For surface data object to be used as background map for this plotting function. nilearn.plotting.plot_surf: For brain surface visualization. nilearn.surface.vol_to_surf : For info on the generation of surfaces. """ loaded_stat_map = load_surf_data(stat_map) # Call _get_colorbar_and_data_ranges to derive symmetric vmin, vmax # And colorbar limits depending on symmetric_cbar settings cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( loaded_stat_map, vmax, symmetric_cbar, kwargs) display = plot_surf( surf_mesh, surf_map=loaded_stat_map, bg_map=bg_map, hemi=hemi, view=view, engine=engine, avg_method='mean', threshold=threshold, cmap=cmap, symmetric_cmap=True, colorbar=colorbar, cbar_tick_format=cbar_tick_format, alpha=alpha, bg_on_data=bg_on_data, darkness=darkness, vmax=vmax, vmin=vmin, title=title, title_font_size=title_font_size, output_file=output_file, axes=axes, figure=figure, cbar_vmin=cbar_vmin, cbar_vmax=cbar_vmax, **kwargs ) return display
def test_get_colorbar_and_data_ranges_pos(): # data with positive range data_pos = np.array([[0, 1., np.nan], [0., np.nan, 0], [1.5, 2.5, 3.]]) # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=None, symmetric_cbar=True, kwargs={}) assert_equal(vmin, -np.nanmax(data_pos)) assert_equal(vmax, np.nanmax(data_pos)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=2, symmetric_cbar=True, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=None, symmetric_cbar=False, kwargs={}) assert_equal(vmin, -np.nanmax(data_pos)) assert_equal(vmax, np.nanmax(data_pos)) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=2, symmetric_cbar=False, kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None) # symmetric_cbar is set to 'auto', same behaviour as false in this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=None, symmetric_cbar='auto', kwargs={}) assert_equal(vmin, -np.nanmax(data_pos)) assert_equal(vmax, np.nanmax(data_pos)) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( data_pos, vmax=2, symmetric_cbar='auto', kwargs={}) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, 0) assert_equal(cbar_vmax, None)
def jumeg_plot_stat_map(stat_map_img, t, bg_img=MNI152TEMPLATE, cut_coords=None, output_file=None, display_mode='ortho', colorbar=True, figure=None, axes=None, title=None, threshold=1e-6, annotate=True, draw_cross=True, black_bg='auto', cmap='magma', symmetric_cbar="auto", cbar_range=None, dim='auto', vmax=None, resampling_interpolation='continuous', **kwargs): """ Plot cuts of an ROI/mask image (by default 3 cuts: Frontal, Axial, and Lateral) This is based on nilearn.plotting.plot_stat_map Parameters ---------- stat_map_img : Niimg-like object See http://nilearn.github.io/manipulating_images/input_output.html The statistical map image t : int Plot activity at time point given by time t. bg_img : Niimg-like object See http://nilearn.github.io/manipulating_images/input_output.html The background image that the ROI/mask will be plotted on top of. If nothing is specified, the MNI152 template will be used. To turn off background image, just pass "bg_img=False". cut_coords : None, a tuple of floats, or an integer The MNI coordinates of the point where the cut is performed If display_mode is 'ortho', this should be a 3-tuple: (x, y, z) For display_mode == 'x', 'y', or 'z', then these are the coordinates of each cut in the corresponding direction. If None is given, the cuts is calculated automaticaly. If display_mode is 'x', 'y' or 'z', cut_coords can be an integer, in which case it specifies the number of cuts to perform output_file : string, or None, optional The name of an image file to export the plot to. Valid extensions are .png, .pdf, .svg. If output_file is not None, the plot is saved to a file, and the display is closed. display_mode : {'ortho', 'x', 'y', 'z', 'yx', 'xz', 'yz'} Choose the direction of the cuts: 'x' - sagittal, 'y' - coronal, 'z' - axial, 'ortho' - three cuts are performed in orthogonal directions. colorbar : boolean, optional If True, display a colorbar on the right of the plots. figure : integer or matplotlib figure, optional Matplotlib figure used or its number. If None is given, a new figure is created. axes : matplotlib axes or 4 tuple of float: (xmin, ymin, width, height), optional The axes, or the coordinates, in matplotlib figure space, of the axes used to display the plot. If None, the complete figure is used. title : string, optional The title displayed on the figure. threshold : a number, None, or 'auto' If None is given, the image is not thresholded. If a number is given, it is used to threshold the image: values below the threshold (in absolute value) are plotted as transparent. If auto is given, the threshold is determined magically by analysis of the image. annotate : boolean, optional If annotate is True, positions and left/right annotation are added to the plot. draw_cross : boolean, optional If draw_cross is True, a cross is drawn on the plot to indicate the cut plosition. black_bg : boolean, optional If True, the background of the image is set to be black. If you wish to save figures with a black background, you will need to pass "facecolor='k', edgecolor='k'" to matplotlib.pyplot.savefig. cmap : matplotlib colormap, optional The colormap for specified image. The ccolormap *must* be symmetrical. symmetric_cbar : boolean or 'auto', optional, default 'auto' Specifies whether the colorbar should range from -vmax to vmax or from vmin to vmax. Setting to 'auto' will select the latter if the range of the whole image is either positive or negative. Note: The colormap will always be set to range from -vmax to vmax. cbar_range : None, 2-tuple Color range of the plot. dim : float, 'auto' (by default), optional Dimming factor applied to background image. By default, automatic heuristics are applied based upon the background image intensity. Accepted float values, where a typical scan is between -2 and 2 (-2 = increase constrast; 2 = decrease contrast), but larger values can be used for a more pronounced effect. 0 means no dimming. vmax : float Upper bound for plotting, passed to matplotlib.pyplot.imshow resampling_interpolation : str Interpolation to use when resampling the image to the destination space. Can be "continuous" (default) to use 3rd-order spline interpolation, or "nearest" to use nearest-neighbor mapping. "nearest" is faster but can be noisier in some cases. Notes ----- Arrays should be passed in numpy convention: (x, y, z) ordered. For visualization, non-finite values found in passed 'stat_map_img' or 'bg_img' are set to zero. See Also -------- nilearn.plotting.plot_anat : To simply plot anatomical images nilearn.plotting.plot_epi : To simply plot raw EPI images nilearn.plotting.plot_glass_brain : To plot maps in a glass brain """ # noqa: E501 # dim the background from nilearn.plotting.img_plotting import _load_anat, _plot_img_with_bg, _get_colorbar_and_data_ranges from nilearn._utils import check_niimg_3d, check_niimg_4d from nilearn._utils.niimg_conversions import _safe_get_data bg_img, black_bg, bg_vmin, bg_vmax = _load_anat(bg_img, dim=dim, black_bg=black_bg) stat_map_img = check_niimg_4d(stat_map_img, dtype='auto') cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges(_safe_get_data(stat_map_img, ensure_finite=True), vmax, symmetric_cbar, kwargs) if cbar_range is not None: cbar_vmin = cbar_range[0] cbar_vmax = cbar_range[1] vmin = cbar_range[0] vmax = cbar_range[1] stat_map_img_at_time_t = index_img(stat_map_img, t) stat_map_img_at_time_t = check_niimg_3d(stat_map_img_at_time_t, dtype='auto') display = _plot_img_with_bg( img=stat_map_img_at_time_t, bg_img=bg_img, cut_coords=cut_coords, output_file=output_file, display_mode=display_mode, figure=figure, axes=axes, title=title, annotate=annotate, draw_cross=draw_cross, black_bg=black_bg, threshold=threshold, bg_vmin=bg_vmin, bg_vmax=bg_vmax, cmap=cmap, vmin=vmin, vmax=vmax, colorbar=colorbar, cbar_vmin=cbar_vmin, cbar_vmax=cbar_vmax, resampling_interpolation=resampling_interpolation, **kwargs) return display
def test_get_colorbar_and_data_ranges_masked_array(): # data with positive and negative range data = np.array([[-.5, 1., np.nan], [0., np.nan, -.2], [1.5, 2.5, 3.]]) masked_data = np.ma.masked_greater(data, 2.) # Easier to fill masked values with NaN to test against later on filled_data = masked_data.filled(np.nan) # Reasonable additional arguments that would end up being passed # to imshow in a real plotting use case kwargs = {'aspect': 'auto', 'alpha': 0.9} # symmetric_cbar set to True cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( masked_data, vmax=None, symmetric_cbar=True, kwargs=kwargs) assert_equal(vmin, -np.nanmax(filled_data)) assert_equal(vmax, np.nanmax(filled_data)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( masked_data, vmax=2, symmetric_cbar=True, kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # symmetric_cbar is set to False cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( masked_data, vmax=None, symmetric_cbar=False, kwargs=kwargs) assert_equal(vmin, -np.nanmax(filled_data)) assert_equal(vmax, np.nanmax(filled_data)) assert_equal(cbar_vmin, np.nanmin(filled_data)) assert_equal(cbar_vmax, np.nanmax(filled_data)) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( masked_data, vmax=2, symmetric_cbar=False, kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, np.nanmin(filled_data)) assert_equal(cbar_vmax, np.nanmax(filled_data)) # symmetric_cbar is set to 'auto', same behaviours as True for this case cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( masked_data, vmax=None, symmetric_cbar='auto', kwargs=kwargs) assert_equal(vmin, -np.nanmax(filled_data)) assert_equal(vmax, np.nanmax(filled_data)) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None) # same case if vmax has been set cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( masked_data, vmax=2, symmetric_cbar='auto', kwargs=kwargs) assert_equal(vmin, -2) assert_equal(vmax, 2) assert_equal(cbar_vmin, None) assert_equal(cbar_vmax, None)
def plot_surf_roi(surf_mesh, roi_map, bg_map=None, hemi='left', view='lateral', alpha='auto', vmin=None, vmax=None, cmap='gist_ncar', bg_on_data=False, darkness=1, title=None, output_file=None, axes=None, figure=None, **kwargs): """ Plotting of surfaces with optional background and stats map .. versionadded:: 0.3 Parameters ---------- surf_mesh : str or list of two numpy.ndarray Surface mesh geometry, can be a file (valid formats are .gii or Freesurfer specific files such as .orig, .pial, .sphere, .white, .inflated) or a list of two Numpy arrays, the first containing the x-y-z coordinates of the mesh vertices, the second containing the indices (into coords) of the mesh faces roi_map : str or numpy.ndarray or list of numpy.ndarray ROI map to be displayed on the surface mesh, can be a file (valid formats are .gii, .mgz, .nii, .nii.gz, or Freesurfer specific files such as .annot or .label), or a Numpy array containing a value for each vertex, or a list of Numpy arrays, one array per ROI which contains indices of all vertices included in that ROI. hemi : {'left', 'right'}, default is 'left' Hemisphere to display. bg_map : Surface data object (to be defined), optional, Background image to be plotted on the mesh underneath the stat_map in greyscale, most likely a sulcal depth map for realistic shading. view: {'lateral', 'medial', 'dorsal', 'ventral', 'anterior', 'posterior'}, default is 'lateral' View of the surface that is rendered. cmap : matplotlib colormap str or colormap object, default 'coolwarm' To use for plotting of the rois. Either a string which is a name of a matplotlib colormap, or a matplotlib colormap object. alpha : float, default is 'auto' Alpha level of the mesh (not the stat_map). If default, alpha will default to .5 when no bg_map is passed and to 1 if a bg_map is passed. bg_on_data : bool, default is False If True, and a bg_map is specified, the stat_map data is multiplied by the background image, so that e.g. sulcal depth is visible beneath the stat_map. Beware that this non-uniformly changes the stat_map values according to e.g the sulcal depth. darkness : float, between 0 and 1, default is 1 Specifying the darkness of the background image. 1 indicates that the original values of the background are used. .5 indicates the background values are reduced by half before being applied. title : str, optional Figure title. output_file: str, or None, optional The name of an image file to export plot to. Valid extensions are .png, .pdf, .svg. If output_file is not None, the plot is saved to a file, and the display is closed. axes: Axes instance | None The axes instance to plot to. The projection must be '3d' (e.g., `plt.subplots(subplot_kw={'projection': '3d'})`). If None, a new axes is created. figure: Figure instance | None The figure to plot to. If None, a new figure is created. See Also -------- nilearn.datasets.fetch_surf_fsaverage5: For surface data object to be used as background map for this plotting function. nilearn.plotting.plot_surf: For brain surface visualization. """ v, _ = load_surf_mesh(surf_mesh) # if roi_map is a list of arrays with indices for different rois if isinstance(roi_map, list): roi_list = roi_map[:] roi_map = np.zeros(v.shape[0]) idx = 1 for arr in roi_list: roi_map[arr] = idx idx += 1 elif isinstance(roi_map, np.ndarray): # if roi_map is an array with values for all surface nodes roi_data = load_surf_data(roi_map) # or a single array with indices for a single roi if roi_data.shape[0] != v.shape[0]: roi_map = np.zeros(v.shape[0], dtype=int) roi_map[roi_data] = 1 else: raise ValueError('Invalid input for roi_map. Input can be a file ' '(valid formats are .gii, .mgz, .nii, ' '.nii.gz, or Freesurfer specific files such as ' '.annot or .label), or a Numpy array containing a ' 'value for each vertex, or a list of Numpy arrays, ' 'one array per ROI which contains indices of all ' 'vertices included in that ROI') vmin, vmax = np.min(roi_map), np.max(roi_map) cbar_vmin, cbar_vmax, vmin, vmax = _get_colorbar_and_data_ranges( roi_map, vmax, 'auto', kwargs) display = plot_surf( surf_mesh, surf_map=roi_map, bg_map=bg_map, hemi=hemi, view=view, # removed avg_method keyword cmap=cmap, alpha=alpha, bg_on_data=bg_on_data, darkness=darkness, # vmin=vmin, vmax=vmax, title=title, output_file=output_file, axes=axes, figure=figure, **kwargs) return display