def checkfreq(freqlike_, count): # checks frequency of param, also handles the case where it is specified # as a bool. does not trigger on 0 if ut.is_int(freqlike_): return (count % freqlike_) == (freqlike_ - 1) else: return freqlike_ is True
def set_sorting(model, col_sort_index=None, order=Qt.DescendingOrder): model.sortreverse = order == Qt.DescendingOrder if col_sort_index is not None: if utool.is_str(col_sort_index): col_sort_index = model.col_name_list.index(col_sort_index) assert utool.is_int(col_sort_index), "sort by an index not %r" % type(col_sort_index) model.sortcolumn = col_sort_index assert model.sortcolumn < len(model.col_name_list), "outofbounds" print("sortcolumn: %r" % model.sortcolumn)
def _type_from_data(data): """ If type is not given make an educated guess """ if utool.is_bool(data) or data == 'True' or data == 'False': return bool elif utool.is_int(data): return int elif utool.is_float(data): return float else: return str
def set_sorting(model, col_sort_index=None, order=Qt.DescendingOrder): model.sortreverse = order == Qt.DescendingOrder if col_sort_index is not None: if utool.is_str(col_sort_index): col_sort_index = model.col_name_list.index(col_sort_index) assert utool.is_int( col_sort_index ), 'sort by an index not %r' % type(col_sort_index) model.sortcolumn = col_sort_index assert model.sortcolumn < len(model.col_name_list), 'outofbounds' print('sortcolumn: %r' % model.sortcolumn)
def cast_into_qt(data): """ Casts python data into a representation suitable for QT (usually a string) """ if SIMPLE_CASTING: if ut.is_str(data): return __STR__(data) elif ut.is_float(data): # qnumber = QString.number(float(data), format='g', precision=8) return locale_float(data) elif ut.is_bool(data): return bool(data) elif ut.is_int(data): return int(data) elif isinstance(data, uuid.UUID): return __STR__(data) elif ut.isiterable(data): return ', '.join(map(__STR__, data)) else: return __STR__(data) if ut.is_str(data): return __STR__(data) elif ut.is_float(data): # qnumber = QString.number(float(data), format='g', precision=8) return locale_float(data) elif ut.is_bool(data): return bool(data) elif ut.is_int(data): return int(data) elif isinstance(data, uuid.UUID): return __STR__(data) elif ut.isiterable(data): return ', '.join(map(__STR__, data)) elif data is None: return 'None' else: return 'Unknown qtype: %r for data=%r' % (type(data), data)
def cast_into_qt(data): """ Casts python data into a representation suitable for QT (usually a string) """ if SIMPLE_CASTING: if ut.is_str(data): return __STR__(data) elif ut.is_float(data): #qnumber = QString.number(float(data), format='g', precision=8) return locale_float(data) elif ut.is_bool(data): return bool(data) elif ut.is_int(data): return int(data) elif isinstance(data, uuid.UUID): return __STR__(data) elif ut.isiterable(data): return ', '.join(map(__STR__, data)) else: return __STR__(data) if ut.is_str(data): return __STR__(data) elif ut.is_float(data): #qnumber = QString.number(float(data), format='g', precision=8) return locale_float(data) elif ut.is_bool(data): return bool(data) elif ut.is_int(data): return int(data) elif isinstance(data, uuid.UUID): return __STR__(data) elif ut.isiterable(data): return ', '.join(map(__STR__, data)) elif data is None: return 'None' else: return 'Unknown qtype: %r for data=%r' % (type(data), data)
def testdata_expanded_aids(defaultdb=None, a=None, ibs=None, default_qaids=None, default_daids=None, qaid_override=None, daid_override=None, return_annot_info=False, verbose=None, use_cache=None): r""" Args: default_qaids (list): (default = [1]) default_daids (str): (default = 'all') defaultdb (str): (default = 'testdb1') ibs (IBEISController): ibeis controller object(default = None) verbose (bool): verbosity flag(default = False) return_annot_info (bool): (default = False) Returns: ibs, qaid_list, daid_list, annot_info: CommandLine: python -m ibeis.init.main_helpers testdata_expanded_aids python -m ibeis.init.main_helpers testdata_expanded_aids --db PZ_MTEST --acfg default:index=0:25 --verbose-testdata python -m ibeis.init.main_helpers testdata_expanded_aids --db PZ_MTEST --qaid 3 python -m ibeis.init.main_helpers testdata_expanded_aids --db GZ_ALL --acfg ctrl --verbose-testdata Example: >>> # ENABLE_DOCTEST >>> from ibeis.init.main_helpers import * # NOQA >>> import ibeis >>> from ibeis.expt import annotation_configs >>> ibs, qaid_list, daid_list, aidcfg = testdata_expanded_aids(return_annot_info=True) >>> print('Printing annot config') >>> annotation_configs.print_acfg(aidcfg) >>> print('Printing annotconfig stats') >>> ibs.print_annotconfig_stats(qaid_list, daid_list) >>> print('Combined annotconfig stats') >>> ibs.print_annot_stats(qaid_list + daid_list, viewcode_isect=True) >>> print('qaid_list = %r' % (qaid_list,)) """ if verbose is None: verbose = 1 if verbose: print('[main_helpers] testdata_expanded_aids') default_qaids = ut.get_argval(('--qaid', '--qaid-override'), type_=list, default=default_qaids) if default_qaids is None: default_qaids = [1] if defaultdb is None: defaultdb = 'testdb1' import ibeis if ibs is None: ibs = ibeis.opendb(defaultdb=defaultdb) # TODO: rectify command line with function arguments from ibeis.expt import experiment_helpers _specified2 = True if a is None: _specified2 = False a = ['default'] if isinstance(a, six.string_types): a = [a] aidcfg_name_list, _specified = ut.get_argval(('--aidcfg', '--acfg', '-a'), type_=list, default=a, return_specified=True) if not _specified: # Allow a to be specified an explicit default if len(a) == 2: qaids, daids = a if ut.is_int(qaids[0]) and ut.is_int(daids[0]): if return_annot_info: return ibs, qaids, daids, None else: return ibs, qaids, daids acfg_list, expanded_aids_list = experiment_helpers.get_annotcfg_list( ibs, aidcfg_name_list, qaid_override=qaid_override, use_cache=use_cache, daid_override=daid_override, verbose=max(0, verbose - 1)) #aidcfg = old_main_helpers.get_commandline_aidcfg() assert len(acfg_list) == 1, ( ('multiple acfgs specified, but this function' 'is built to return only 1. len(acfg_list)=%r') % (len(acfg_list), )) aidcfg = acfg_list[0] qaid_list, daid_list = expanded_aids_list[0] if not (_specified or _specified2): # hack if default_qaids is not None and qaid_override is None: qaid_list = default_qaids if default_daids is not None and daid_override is None: daid_list = default_daids if ut.VERYVERBOSE: ibs.print_annotconfig_stats(qaid_list, daid_list) #ibeis.other.dbinfo.print_qd_info(ibs, qaid_list, daid_list, verbose=True) if return_annot_info: return ibs, qaid_list, daid_list, aidcfg else: return ibs, qaid_list, daid_list
def batch_iterator(model, X, y, randomize_batch_order=False, augment_on=False, X_is_cv2_native=True, verbose=None, lbl='verbose batch iteration'): r""" Breaks up data into to batches defined by model batch size CommandLine: python -m ibeis_cnn --tf batch_iterator:0 python -m ibeis_cnn --tf batch_iterator:1 python -m ibeis_cnn --tf batch_iterator:2 python -m ibeis_cnn --tf batch_iterator:1 --DEBUG_AUGMENTATION python -m ibeis_cnn --tf batch_iterator:1 --noaugment # Threaded buffering seems to help a lot python -m ibeis_cnn --tf batch_iterator:1 --augment Example0: >>> # ENABLE_DOCTEST >>> from ibeis_cnn.batch_processing import * # NOQA >>> from ibeis_cnn import models >>> model = models.DummyModel(batch_size=16) >>> X, y = model.make_random_testdata(num=99, seed=None, cv2_format=True) >>> model.ensure_data_params(X, y) >>> y = None >>> encoder = None >>> randomize_batch_order = True >>> result_list = [(Xb, Yb) for Xb, Yb in batch_iterator(model, X, y, ... randomize_batch_order)] >>> result = ut.depth_profile(result_list, compress_consecutive=True) >>> print(result) [[(16, 1, 4, 4), 16]] * 6 + [[(3, 1, 4, 4), 3]] Example1: >>> # ENABLE_DOCTEST >>> from ibeis_cnn.batch_processing import * # NOQA >>> from ibeis_cnn import models >>> import time >>> model = models.SiameseL2(batch_size=128, data_shape=(8, 8, 1)) >>> X, y = model.make_random_testdata(num=1000, seed=None, cv2_format=True) >>> model.ensure_data_params(X, y) >>> encoder = None >>> result_list1 = [] >>> result_list2 = [] >>> augment_on=not ut.get_argflag('--noaugment') >>> iterkw = dict(randomize_batch_order=True, >>> augment_on=augment_on, >>> showprog=True, verbose=ut.VERBOSE) >>> sleep_time = .05 >>> inside_time1 = 0 >>> inside_time2 = 0 >>> with ut.Timer('buffered') as t2: >>> generator = batch_iterator(model, X, y, **iterkw) >>> for Xb, Yb in ut.buffered_generator(generator, buffer_size=3): >>> with ut.Timer('Inside', verbose=False) as t: >>> time.sleep(sleep_time) >>> result_list2.append(Xb.shape) >>> inside_time2 += t.ellapsed >>> with ut.Timer('unbuffered') as t1: >>> generator = batch_iterator(model, X, y, **iterkw) >>> for Xb, Yb in generator: >>> with ut.Timer('Inside', verbose=False) as t: >>> time.sleep(sleep_time) >>> result_list1.append(Xb.shape) >>> inside_time1 += t.ellapsed >>> print('\nInside times should be the same') >>> print('inside_time1 = %r' % (inside_time1,)) >>> print('inside_time2 = %r' % (inside_time2,)) >>> print('Outside times show the overhead of data augmentation') >>> print('Overhead Unbuffered = %r' % (t1.ellapsed - inside_time1,)) >>> print('Overhead Buffered = %r' % (t2.ellapsed - inside_time2,)) >>> print('Efficiency Unbuffered = %.2f' % (100 * inside_time1 / t1.ellapsed,)) >>> print('Efficiency Buffered = %.2f' % (100 * inside_time2 / t2.ellapsed,)) >>> assert result_list1 == result_list2 >>> print(len(result_list2)) Example2: >>> # DISABLE_DOCTEST >>> from ibeis_cnn.batch_processing import * # NOQA >>> from ibeis_cnn.models.mnist import MNISTModel >>> from ibeis_cnn import ingest_data >>> # should yield float32 regardlesss of original format >>> ut.exec_funckw(batch_iterator, globals()) >>> randomize_batch_order = False >>> # --- >>> dataset1 = ingest_data.grab_mnist_category_dataset_float() >>> model1 = MNISTModel(batch_size=8, data_shape=dataset1.data_shape, >>> output_dims=dataset1.output_dims, >>> arch_tag=dataset1.alias_key, >>> training_dpath=dataset1.training_dpath) >>> X1, y1 = dataset1.subset('train') >>> model1.ensure_data_params(X1, y1) >>> _iter1 = batch_iterator(model1, X1, y1, randomize_batch_order) >>> Xb1, yb1 = six.next(_iter1) >>> # --- >>> dataset2 = ingest_data.grab_mnist_category_dataset() >>> model2 = MNISTModel(batch_size=8, data_shape=dataset2.data_shape, >>> output_dims=dataset2.output_dims, >>> arch_tag=dataset2.alias_key, >>> training_dpath=dataset2.training_dpath) >>> X2, y2 = dataset2.subset('train') >>> model2.ensure_data_params(X2, y2) >>> _iter2 = batch_iterator(model2, X2, y2, randomize_batch_order) >>> Xb2, yb2 = six.next(_iter2) >>> # --- >>> X, y, model = X1, y1, model1 >>> assert np.all(yb2 == yb2) >>> # The uint8 and float32 data should produce similar values >>> # For this mnist set it will be a bit more off because the >>> # original uint8 scaling value was 256 not 255. >>> assert (Xb1[0] - Xb2[0]).max() < .1 >>> assert np.isclose(Xb1.mean(), 0, atol=.01) >>> assert np.isclose(Xb2.mean(), 0, atol=.01) >>> assert Xb1.max() < 1.0 and Xb2.max() < 1.0, 'out of (-1, 1)' >>> assert Xb1.min() > -1.0 and Xb1.min() > -1.0, 'out of (-1, 1)' >>> assert Xb1.min() < 0, 'should have some negative values' >>> assert Xb2.min() < 0, 'should have some negative values' >>> assert Xb1.max() > 0, 'should have some positive values' >>> assert Xb2.max() > 0, 'should have some positive values' """ if verbose: verbose = VERBOSE_BATCH # need to be careful with batchsizes if directly specified to theano wraparound = model.input_shape[0] is not None augment_on = augment_on and hasattr(model, 'augment') encoder = getattr(model, 'encoder', None) needs_convert = ut.is_int(X) if y is not None: assert X.shape[0] == (y.shape[0] * model.data_per_label_input), ( 'bad data / label alignment') num_batches = (X.shape[0] + model.batch_size - 1) // model.batch_size if randomize_batch_order: # Randomly shuffle data # 0.079 mnist time fraction X, y = utils.data_label_shuffle(X, y, model.data_per_label_input) if verbose: print('[batchiter] BEGIN') print('[batchiter] X.shape %r' % (X.shape, )) if y is not None: print('[batchiter] y.shape %r' % (y.shape, )) print('[batchiter] augment_on %r' % (augment_on, )) print('[batchiter] encoder %r' % (encoder, )) print('[batchiter] wraparound %r' % (wraparound, )) print('[batchiter] model.data_per_label_input %r' % (model.data_per_label_input, )) print('[batchiter] needs_convert = %r' % (needs_convert,)) # FIXME: put in a layer? center_mean = None center_std = None # Load precomputed whitening parameters if model.data_params is not None: center_mean = np.array(model.data_params['center_mean'], dtype=np.float32) center_std = np.array(model.data_params['center_std'], dtype=np.float32) do_whitening = (center_mean is not None and center_std is not None and center_std != 0.0) if needs_convert: ceneter_mean01 = center_mean / np.array(255.0, dtype=np.float32) center_std01 = center_std / np.array(255.0, dtype=np.float32) else: ceneter_mean01 = center_mean center_std01 = center_std # Slice and preprocess data in batch for batch_index in range(num_batches): # Take a slice from the data Xb_orig, yb_orig = utils.slice_data_labels( X, y, model.batch_size, batch_index, model.data_per_label_input, wraparound=wraparound) # Ensure correct format for the GPU Xb = Xb_orig.astype(np.float32) yb = None if yb_orig is None else yb_orig.astype(np.int32) if needs_convert: # Rescale the batch data to the range 0 to 1 Xb = Xb / 255.0 if augment_on: # Apply defined transformations Xb, yb, = augment_batch(model, Xb, yb, batch_index, verbose, num_batches) if do_whitening: # Center the batch data in the range (-1.0, 1.0) Xb = (Xb - ceneter_mean01) / (center_std01) if X_is_cv2_native: # Convert from cv2 to lasange format Xb = Xb.transpose((0, 3, 1, 2)) if yb is not None: if encoder is not None: # Apply an encoding if applicable yb = encoder.transform(yb).astype(np.int32) if model.data_per_label_input > 1 and getattr(model, 'needs_padding', False): # Pad data for siamese networks yb = pad_labels(model, yb) if verbose: # Print info if requested print_batch_info(Xb, yb, verbose, batch_index, num_batches) yield Xb, yb if verbose: print('[batch] END')
def figure(fnum=None, pnum=(1, 1, 1), docla=False, title=None, figtitle=None, doclf=False, projection=None, **kwargs): """ TODO: gridspec http://matplotlib.org/users/gridspec.html Args: fnum (int): fignum = figure number pnum (int, str, or tuple(int, int, int)): plotnum = plot tuple Args: fnum (int): fignum = figure number pnum (int, str, or tuple(int, int, int)): plotnum = plot tuple docla (bool): (default = False) title (str): (default = None) figtitle (None): (default = None) doclf (bool): (default = False) projection (None): (default = None) Returns: ?: fig CommandLine: python -m plottool.custom_figure --exec-figure:0 --show python -m plottool.custom_figure --exec-figure:1 --show Example: >>> # ENABLE_DOCTEST >>> from plottool.custom_figure import * # NOQA >>> fnum = 1 >>> fig = figure(fnum, (2, 2, 1)) >>> gca().text(0.5, 0.5, "ax1", va="center", ha="center") >>> fig = figure(fnum, (2, 2, 2)) >>> gca().text(0.5, 0.5, "ax2", va="center", ha="center") >>> ut.show_if_requested() Example: >>> # ENABLE_DOCTEST >>> from plottool.custom_figure import * # NOQA >>> fnum = 1 >>> fig = figure(fnum, (2, 2, 1)) >>> gca().text(0.5, 0.5, "ax1", va="center", ha="center") >>> fig = figure(fnum, (2, 2, 2)) >>> gca().text(0.5, 0.5, "ax2", va="center", ha="center") >>> fig = figure(fnum, (2, 4, (1, slice(1, None)))) >>> gca().text(0.5, 0.5, "ax3", va="center", ha="center") >>> ut.show_if_requested() """ #mpl.pyplot.xkcd() fig = get_fig(fnum) axes_list = fig.get_axes() # Ensure my customized settings customize_figure(fig, docla) if ut.is_int(pnum): pnum = _convert_pnum_int_to_tup(pnum) def pnum_to_subspec(pnum): if isinstance(pnum, six.string_types): pnum = list(pnum) #if isinstance(pnum, (list, tuple)): nrow, ncols, plotnum = pnum if kwargs.get('use_gridspec', True): # Convert old pnums to gridspec gs = gridspec.GridSpec(nrow, ncols) if isinstance(plotnum, (tuple, slice, list)): subspec = gs[plotnum] else: subspec = gs[plotnum - 1] return (subspec, ) else: return (nrow, ncols, plotnum) if doclf: # a bit hacky. Need to rectify docla and doclf fig.clf() # <HACK TO CLEAR AXES> #for ax in axes_list: # ax.clear() #for ax in fig.get_axes: # fig.delaxes(ax) #axes_list = [] # </HACK TO CLEAR AXES> # Get the subplot if docla or len(axes_list) == 0: #printDBG('[df2] *** NEW FIGURE %r.%r ***' % (fnum, pnum)) if pnum is not None: assert pnum[0] > 0, 'nRows must be > 0: pnum=%r' % (pnum, ) assert pnum[1] > 0, 'nCols must be > 0: pnum=%r' % (pnum, ) #ax = plt.subplot(*pnum) subspec = pnum_to_subspec(pnum) ax = fig.add_subplot(*subspec, projection=projection) #ax = fig.add_subplot(*pnum, projection=projection) ax.cla() else: ax = gca() else: #printDBG('[df2] *** OLD FIGURE %r.%r ***' % (fnum, pnum)) if pnum is not None: subspec = pnum_to_subspec(pnum) ax = plt.subplot(*subspec) #ax = plt.subplot(nrow, ncols, plotnum) #ax = plt.subplot(*pnum) # fig.add_subplot fails here #ax = fig.add_subplot(*pnum) else: ax = gca() #ax = axes_list[0] # Set the title if title is not None: ax = gca() set_title(title, ax=ax) # Add title to figure # HACK HACK HACK if figtitle is None and pnum == (1, 1, 1): figtitle = title if figtitle is not None: set_figtitle(figtitle, incanvas=False) return fig
def figure(fnum=None, pnum=(1, 1, 1), docla=False, title=None, figtitle=None, doclf=False, projection=None, **kwargs): """ TODO: gridspec http://matplotlib.org/users/gridspec.html Args: fnum (int): fignum = figure number pnum (int, str, or tuple(int, int, int)): plotnum = plot tuple Args: fnum (int): fignum = figure number pnum (int, str, or tuple(int, int, int)): plotnum = plot tuple docla (bool): (default = False) title (str): (default = None) figtitle (None): (default = None) doclf (bool): (default = False) projection (None): (default = None) Returns: ?: fig CommandLine: python -m plottool.custom_figure --exec-figure:0 --show python -m plottool.custom_figure --exec-figure:1 --show Example: >>> # ENABLE_DOCTEST >>> from plottool.custom_figure import * # NOQA >>> fnum = 1 >>> fig = figure(fnum, (2, 2, 1)) >>> gca().text(0.5, 0.5, "ax1", va="center", ha="center") >>> fig = figure(fnum, (2, 2, 2)) >>> gca().text(0.5, 0.5, "ax2", va="center", ha="center") >>> ut.show_if_requested() Example: >>> # ENABLE_DOCTEST >>> from plottool.custom_figure import * # NOQA >>> fnum = 1 >>> fig = figure(fnum, (2, 2, 1)) >>> gca().text(0.5, 0.5, "ax1", va="center", ha="center") >>> fig = figure(fnum, (2, 2, 2)) >>> gca().text(0.5, 0.5, "ax2", va="center", ha="center") >>> fig = figure(fnum, (2, 4, (1, slice(1, None)))) >>> gca().text(0.5, 0.5, "ax3", va="center", ha="center") >>> ut.show_if_requested() """ #mpl.pyplot.xkcd() fig = get_fig(fnum) axes_list = fig.get_axes() # Ensure my customized settings customize_figure(fig, docla) if ut.is_int(pnum): pnum = _convert_pnum_int_to_tup(pnum) def pnum_to_subspec(pnum): if isinstance(pnum, six.string_types): pnum = list(pnum) #if isinstance(pnum, (list, tuple)): nrow, ncols, plotnum = pnum if kwargs.get('use_gridspec', True): # Convert old pnums to gridspec gs = gridspec.GridSpec(nrow, ncols) if isinstance(plotnum, (tuple, slice, list)): subspec = gs[plotnum] else: subspec = gs[plotnum - 1] return (subspec,) else: return (nrow, ncols, plotnum) if doclf: # a bit hacky. Need to rectify docla and doclf fig.clf() # <HACK TO CLEAR AXES> #for ax in axes_list: # ax.clear() #for ax in fig.get_axes: # fig.delaxes(ax) #axes_list = [] # </HACK TO CLEAR AXES> # Get the subplot if docla or len(axes_list) == 0: #printDBG('[df2] *** NEW FIGURE %r.%r ***' % (fnum, pnum)) if pnum is not None: assert pnum[0] > 0, 'nRows must be > 0: pnum=%r' % (pnum,) assert pnum[1] > 0, 'nCols must be > 0: pnum=%r' % (pnum,) #ax = plt.subplot(*pnum) subspec = pnum_to_subspec(pnum) ax = fig.add_subplot(*subspec, projection=projection) #ax = fig.add_subplot(*pnum, projection=projection) ax.cla() else: ax = gca() else: #printDBG('[df2] *** OLD FIGURE %r.%r ***' % (fnum, pnum)) if pnum is not None: subspec = pnum_to_subspec(pnum) ax = plt.subplot(*subspec) #ax = plt.subplot(nrow, ncols, plotnum) #ax = plt.subplot(*pnum) # fig.add_subplot fails here #ax = fig.add_subplot(*pnum) else: ax = gca() #ax = axes_list[0] # Set the title if title is not None: ax = gca() set_title(title, ax=ax) # Add title to figure # HACK HACK HACK if figtitle is None and pnum == (1, 1, 1): figtitle = title if figtitle is not None: set_figtitle(figtitle, incanvas=False) return fig
def figure( fnum=None, pnum=(1, 1, 1), docla=False, title=None, figtitle=None, doclf=False, projection=None, **kwargs, ): """ http://matplotlib.org/users/gridspec.html Args: fnum (int): fignum = figure number pnum (int, str, or tuple(int, int, int)): plotnum = plot tuple docla (bool): (default = False) title (str): (default = None) figtitle (None): (default = None) doclf (bool): (default = False) projection (None): (default = None) Returns: ?: fig CommandLine: python -m wbia.plottool.custom_figure --exec-figure:0 --show python -m wbia.plottool.custom_figure --exec-figure:1 --show Example: >>> # ENABLE_DOCTEST >>> from wbia.plottool.custom_figure import * # NOQA >>> fnum = 1 >>> fig = figure(fnum, (2, 2, 1)) >>> gca().text(0.5, 0.5, "ax1", va="center", ha="center") >>> fig = figure(fnum, (2, 2, 2)) >>> gca().text(0.5, 0.5, "ax2", va="center", ha="center") >>> import wbia.plottool as pt >>> pt.show_if_requested() Example: >>> # ENABLE_DOCTEST >>> from wbia.plottool.custom_figure import * # NOQA >>> fnum = 1 >>> fig = figure(fnum, (2, 2, 1)) >>> gca().text(0.5, 0.5, "ax1", va="center", ha="center") >>> fig = figure(fnum, (2, 2, 2)) >>> gca().text(0.5, 0.5, "ax2", va="center", ha="center") >>> fig = figure(fnum, (2, 4, (1, slice(1, None)))) >>> gca().text(0.5, 0.5, "ax3", va="center", ha="center") >>> import wbia.plottool as pt >>> pt.show_if_requested() """ # mpl.pyplot.xkcd() fig = ensure_fig(fnum) axes_list = fig.get_axes() # Ensure my customized settings customize_figure(fig, docla) if pnum is None: return fig if ut.is_int(pnum): pnum = _convert_pnum_int_to_tup(pnum) if doclf: fig.clf() if docla or len(axes_list) == 0: if pnum is not None: assert pnum[0] > 0, 'nRows must be > 0: pnum=%r' % (pnum, ) assert pnum[1] > 0, 'nCols must be > 0: pnum=%r' % (pnum, ) subspec = _pnum_to_subspec(pnum) ax = fig.add_subplot(*subspec, projection=projection) if docla: ax.cla() else: ax = gca() else: if pnum is not None: subspec = _pnum_to_subspec(pnum) ax = plt.subplot(*subspec) else: ax = gca() # Set the title / figtitle if title is not None: ax = gca() set_title(title, ax=ax) if figtitle is not None: set_figtitle(figtitle, incanvas=False, fig=fig) return fig