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

Address several warnings raised during tests #1351

Merged
merged 19 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 25 additions & 16 deletions qiskit_experiments/visualization/drawers/mpl_drawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,31 @@ def format_canvas(self):
else:
all_axes = [self._axis]

# Set axes scale. This needs to be done before anything tries work with
wshanks marked this conversation as resolved.
Show resolved Hide resolved
# the axis limits because if no limits or data are set explicitly the
# default limits depend on the scale method (for example, the minimum
# value is 0 for linear scaling but not for log scaling).
def signed_sqrt(x):
return np.sign(x) * np.sqrt(abs(x))

def signed_square(x):
return np.sign(x) * x**2

for ax_type in ("x", "y"):
for sub_ax in all_axes:
scale = self.figure_options.get(f"{ax_type}scale")
if ax_type == "x":
mpl_setscale = sub_ax.set_xscale
else:
mpl_setscale = sub_ax.set_yscale

# Apply non linear axis spacing
if scale is not None:
if scale == "quadratic":
mpl_setscale("function", functions=(signed_square, signed_sqrt))
else:
mpl_setscale(scale)

# Get axis formatter from drawing options
formatter_opts = {}
for ax_type in ("x", "y"):
Expand Down Expand Up @@ -181,12 +206,6 @@ def format_canvas(self):
"max_ax_vals": max_vals,
}

def signed_sqrt(x):
return np.sign(x) * np.sqrt(abs(x))

def signed_square(x):
return np.sign(x) * x**2

for i, sub_ax in enumerate(all_axes):
# Add data labels if there are multiple labels registered per sub_ax.
_, labels = sub_ax.get_legend_handles_labels()
Expand All @@ -197,18 +216,15 @@ def signed_square(x):
limit = formatter_opts[ax_type]["limit"][i]
unit = formatter_opts[ax_type]["unit"][i]
unit_scale = formatter_opts[ax_type]["unit_scale"][i]
scale = self.figure_options.get(f"{ax_type}scale")
min_ax_vals = formatter_opts[ax_type]["min_ax_vals"]
max_ax_vals = formatter_opts[ax_type]["max_ax_vals"]
share_axis = self.figure_options.get(f"share{ax_type}")

if ax_type == "x":
mpl_setscale = sub_ax.set_xscale
mpl_axis_obj = getattr(sub_ax, "xaxis")
mpl_setlimit = sub_ax.set_xlim
mpl_share = sub_ax.sharex
else:
mpl_setscale = sub_ax.set_yscale
mpl_axis_obj = getattr(sub_ax, "yaxis")
mpl_setlimit = sub_ax.set_ylim
mpl_share = sub_ax.sharey
Expand All @@ -219,13 +235,6 @@ def signed_square(x):
else:
limit = min_ax_vals[i], max_ax_vals[i]

# Apply non linear axis spacing
if scale is not None:
if scale == "quadratic":
mpl_setscale("function", functions=(signed_square, signed_sqrt))
else:
mpl_setscale(scale)

# Create formatter for axis tick label notation
if unit and unit_scale:
# If value is specified, automatically scale axis magnitude
Expand Down
1 change: 0 additions & 1 deletion test/visualization/test_plotter_mpldrawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ def test_scale(self):
plotter.set_figure_options(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outside the scope of this PR, but we should probably handle the case of a log scale with limit 0 gracefully.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to address this here (see aed5d30). I was able to find a somewhat elegant solution by moving the setting of the axis scale earlier in the process (see the commit message). The tricky part is that the code wants to know the axis limits for the part where it tries to rescale the format (like add a k and hide the 000) but if you have axes that have no data in them matplotlib returns 0,1 by default. If the code didn't do that formatting scaling, I would just change it to not set limits when no user limits were specified so matplotlib could use its default limits.

xscale="quadratic",
yscale="log",
ylim=(0.1, 1.0),
)

plotter.figure()
Expand Down