Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for bit string distance measures (Hamming dist) in plot_histogram #2064

Merged
merged 6 commits into from Apr 3, 2019
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 39 additions & 6 deletions qiskit/tools/visualization/_counts_visualization.py
Expand Up @@ -22,8 +22,29 @@
from matplotlib.ticker import MaxNLocator


def hamming_distance(str1, str2):
"""Calculate the Hamming distance between two bit strings

Args:
str1 (str): First string.
str2 (str): Second string.
Returns:
int: Distance between strings.
Raises:
VisualizationError: Strings not same length
"""
if len(str1) != len(str2):
raise VisualizationError('Strings not same length.')
return sum(s1 != s2 for s1, s2 in zip(str1, str2))


VALID_SORTS = ['asc', 'desc', 'hamming']
DIST_MEAS = {'hamming': hamming_distance}


def plot_histogram(data, figsize=(7, 5), color=None, number_to_keep=None,
sort='asc', legend=None, bar_labels=True, title=None):
sort='asc', target_string=None,
legend=None, bar_labels=True, title=None):
"""Plot a histogram of data.

Args:
Expand All @@ -33,7 +54,8 @@ def plot_histogram(data, figsize=(7, 5), color=None, number_to_keep=None,
color (list or str): String or list of strings for histogram bar colors.
number_to_keep (int): The number of terms to plot and rest
is made into a single bar called 'rest'.
sort (string): Could be 'asc' or 'desc'
sort (string): Could be 'asc', 'desc', or 'hamming'.
target_string (str): Target string if 'sort' is a distance measure.
legend(list): A list of strings to use for labels of the data.
The number of entries must match the length of data (if data is a
list or 1 if it's a dict)
Expand All @@ -50,6 +72,13 @@ def plot_histogram(data, figsize=(7, 5), color=None, number_to_keep=None,
"""
if not HAS_MATPLOTLIB:
raise ImportError('Must have Matplotlib installed.')
if sort not in VALID_SORTS:
raise VisualizationError("Value of sort option, %s, isn't a "
"valid choice. Must be 'asc', "
"'desc', or 'hamming'")
elif sort in DIST_MEAS.keys() and target_string is None:
err_msg = 'Must define target_state when using distance measure.'
nonhermitian marked this conversation as resolved.
Show resolved Hide resolved
raise VisualizationError(err_msg)

if isinstance(data, dict):
data = [data]
Expand All @@ -65,6 +94,14 @@ def plot_histogram(data, figsize=(7, 5), color=None, number_to_keep=None,
if number_to_keep is not None:
labels.append('rest')

if sort in DIST_MEAS.keys():
dist = []
for item in labels:
dist.append(DIST_MEAS[sort](item, target_string))

labels = [list(x) for x in zip(*sorted(zip(dist, labels),
key=lambda pair: pair[0]))][1]

labels_dict = OrderedDict()

# Set bar colors
Expand Down Expand Up @@ -130,10 +167,6 @@ def plot_histogram(data, figsize=(7, 5), color=None, number_to_keep=None,
ax.set_ylim([0., min([1.2, max([1.2 * val for val in all_pvalues])])])
if sort == 'desc':
ax.invert_xaxis()
elif sort != 'asc':
raise VisualizationError("Value of sort option, %s, isn't a "
"valid choice. Must be 'asc' or "
"'desc'")

ax.yaxis.set_major_locator(MaxNLocator(5))
for tick in ax.yaxis.get_major_ticks():
Expand Down