diff --git a/qiskit/tools/visualization/__init__.py b/qiskit/tools/visualization/__init__.py index 3671aad724dd..45c5e883809f 100644 --- a/qiskit/tools/visualization/__init__.py +++ b/qiskit/tools/visualization/__init__.py @@ -11,14 +11,18 @@ from ._circuit_visualization import circuit_drawer, plot_circuit, generate_latex_source,\ latex_circuit_drawer, matplotlib_circuit_drawer, qx_color_scheme -from ._counts_visualization import plot_histogram if ('ipykernel' in sys.modules) and ('spyder' not in sys.modules): import requests if requests.get( 'https://qvisualization.mybluemix.net/').status_code == 200: from .interactive._iplot_state import iplot_state as plot_state + from .interactive._iplot_histogram import iplot_histogram as \ + plot_histogram else: from ._state_visualization import plot_state + from ._counts_visualization import plot_histogram + else: from ._state_visualization import plot_state + from ._counts_visualization import plot_histogram diff --git a/qiskit/tools/visualization/_counts_visualization.py b/qiskit/tools/visualization/_counts_visualization.py index e7af0f22a2ac..cbde3e300c96 100644 --- a/qiskit/tools/visualization/_counts_visualization.py +++ b/qiskit/tools/visualization/_counts_visualization.py @@ -17,35 +17,68 @@ import matplotlib.pyplot as plt -def plot_histogram(data, number_to_keep=False): +def plot_histogram(data, number_to_keep=False, legend=None, options=None): """Plot a histogram of data. - data is a dictionary of {'000': 5, '010': 113, ...} - number_to_keep is the number of terms to plot and rest is made into a - single bar called other values + Args: + data (list or dict): This is either a list of dictionaries containing: + values to represent (ex {'001': 130}) + number_to_keep (int): DEPRECATED the number of terms to plot and rest + is made into a single bar called other values + legend(list): A list of strings to use for labels of the data. + The number of entries must match the lenght of data (if data is a + list or 1 if it's a dict) + options (dict): Representation settings containing + - number_to_keep (integer): groups max values + - show_legend (bool): show legend of graph content + Raises: + Exception: When legend is provided and the length doesn't match the + input data """ - if number_to_keep is not False: - data_temp = dict(Counter(data).most_common(number_to_keep)) - data_temp["rest"] = sum(data.values()) - sum(data_temp.values()) - data = data_temp - - labels = sorted(data) - values = np.array([data[key] for key in labels], dtype=float) - pvalues = values / sum(values) - numelem = len(values) - ind = np.arange(numelem) # the x locations for the groups - width = 0.35 # the width of the bars + if options is None: + options = {} + + if isinstance(data, dict): + data = [data] + if legend and len(legend) != 1: + raise Exception("Length of legendL %s doesn't match number of " + "input executions: %s" % (len(legend), 1)) + else: + if legend and len(legend) != len(data): + raise Exception("Length of legendL %s doesn't match number of " + "input executions: %s" % (len(legend), len(data))) + _, ax = plt.subplots() - rects = ax.bar(ind, pvalues, width, color='seagreen') - # add some text for labels, title, and axes ticks - ax.set_ylabel('Probabilities', fontsize=12) - ax.set_xticks(ind) - ax.set_xticklabels(labels, fontsize=12, rotation=70) - ax.set_ylim([0., min([1.2, max([1.2 * val for val in pvalues])])]) - # attach some text labels - for rect in rects: - height = rect.get_height() - ax.text(rect.get_x() + rect.get_width() / 2., 1.05 * height, - '%f' % float(height), - ha='center', va='bottom') + for item, execution in enumerate(data): + if number_to_keep is not False or ( + 'number_to_keep' in options and options['number_to_keep']): + data_temp = dict(Counter(execution).most_common(number_to_keep)) + data_temp["rest"] = sum(execution.values()) - sum(data_temp.values()) + execution = data_temp + + labels = sorted(execution) + values = np.array([execution[key] for key in labels], dtype=float) + pvalues = values / sum(values) + numelem = len(values) + ind = np.arange(numelem) # the x locations for the groups + width = 0.35 # the width of the bars + label = None + if legend: + label = legend[item] + adj = width * item + rects = ax.bar(ind+adj, pvalues, width, label=label) + # add some text for labels, title, and axes ticks + ax.set_ylabel('Probabilities', fontsize=12) + ax.set_xticks(ind) + ax.set_xticklabels(labels, fontsize=12, rotation=70) + ax.set_ylim([0., min([1.2, max([1.2 * val for val in pvalues])])]) + # attach some text labels + for rect in rects: + height = rect.get_height() + ax.text(rect.get_x() + rect.get_width() / 2., 1.05 * height, + '%f' % float(height), + ha='center', va='bottom') + if legend and ( + 'show_legend' not in options or options['show_legend'] is True): + plt.legend() plt.show() diff --git a/qiskit/tools/visualization/interactive/_iplot_histogram.py b/qiskit/tools/visualization/interactive/_iplot_histogram.py index b6495a631b9a..2d91aeb35538 100644 --- a/qiskit/tools/visualization/interactive/_iplot_histogram.py +++ b/qiskit/tools/visualization/interactive/_iplot_histogram.py @@ -48,17 +48,19 @@ def process_data(data, number_to_keep): return result -def iplot_histogram(executions_results, options=None): +def iplot_histogram(data, number_to_keep=False, options=None, legend=None): """ Create a histogram representation. Graphical representation of the input array using a vertical bars style graph. Args: - executions_results (array): Array of dictionaries containing - - data (dict): values to represent (ex. {'001' : 130}) - - name (string): name to show in the legend - - device (string): Could be 'real' or 'simulated' + data (list or dict): This is either a list of dicts or a single + dict containing the values to represent (ex. {'001' : 130}) + number_to_keep (int): DEPRECATED the number of terms to plot and + rest is made into a single bar called other values + legend (list): A list of strings to use for labels of the data. + The number of entries must match the length of data. options (dict): Representation settings containing - width (integer): graph horizontal size - height (integer): graph vertical size @@ -66,6 +68,9 @@ def iplot_histogram(executions_results, options=None): - number_to_keep (integer): groups max values - show_legend (bool): show legend of graph content - sort (string): Could be 'asc' or 'desc' + Raises: + Exception: When legend is provided and the length doesn't match the + input data """ # HTML @@ -111,12 +116,28 @@ def iplot_histogram(executions_results, options=None): options['show_legend'] = 1 if 'number_to_keep' not in options: - options['number_to_keep'] = 0 + if number_to_keep is False: + options['number_to_keep'] = 0 + elif number_to_keep: + options['number_to_keep'] = number_to_keep data_to_plot = [] - for execution in executions_results: - data = process_data(execution['data'], options['number_to_keep']) - data_to_plot.append({'data': data}) + if isinstance(data, dict): + data = [data] + if legend and len(legend) != 1: + raise Exception("Length of legendL %s doesn't match number of " + "input executions: %s" % (len(legend), 1)) + else: + if legend and len(legend) != len(data): + raise Exception("Length of legendL %s doesn't match number of " + "input executions: %s" % (len(legend), len(data))) + + for item, execution in enumerate(data): + exec_data = process_data(execution, options['number_to_keep']) + out_dict = {'data': exec_data} + if legend: + out_dict['name'] = legend[item] + data_to_plot.append(out_dict) html = html_template.substitute({ 'divNumber': div_number