Skip to content
New issue

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

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

Already on GitHub? # to your account

Fix unusable legend size with long filenames on Mac #2264

Merged
merged 11 commits into from
Oct 27, 2022
64 changes: 24 additions & 40 deletions src/sas/qtgui/Plotting/Plotter.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import math

from PyQt5 import QtGui
from PyQt5 import QtWidgets

import functools
import copy
import sys
import matplotlib as mpl
import numpy as np
import textwrap
from matplotlib.font_manager import FontProperties
from packaging import version

Expand All @@ -24,29 +26,7 @@
import sas.qtgui.Utilities.GuiUtils as GuiUtils
import sas.qtgui.Plotting.PlotUtilities as PlotUtilities

def _legendResize(width, parent):
"""
resize factor for the legend, based on total canvas width
"""
# The factor 4.0 was chosen to look similar in size/ratio to what we had in 4.x
if not hasattr(parent.parent, "manager"):
return None
if parent is None or parent.parent is None or parent.parent.manager is None \
or parent.parent.manager.parent is None or parent.parent.manager.parent._parent is None:
return None

screen_width = parent.parent.manager.parent._parent.screen_width
screen_height = parent.parent.manager.parent._parent.screen_height
screen_factor = screen_width * screen_height

if sys.platform == 'win32':
factor = 4
denomintor = 100
scale_factor = width/denomintor + factor
else:
#Function inferred based on tests for several resolutions
scale_factor = (3e-6*screen_factor + 1)*width/640
return scale_factor
from sas import config

class PlotterWidget(PlotterBase):
"""
Expand Down Expand Up @@ -253,14 +233,28 @@ def plot(self, data=None, color=None, marker=None, hide_error=False, transform=T

# Now add the legend with some customizations.
if self.showLegend:
width=_legendResize(self.canvas.size().width(), self.parent)
if width is not None:
self.legend = ax.legend(loc='upper right', shadow=True, prop={'size':width})
max_legend_width = config.FITTING_PLOT_LEGEND_MAX_LINE_LENGTH
handles, labels = ax.get_legend_handles_labels()
newhandles = []
newlabels = []
for h,l in zip(handles,labels):
if config.FITTING_PLOT_LEGEND_TRUNCATE:
if len(l)> config.FITTING_PLOT_LEGEND_MAX_LINE_LENGTH:
half_legend_width = math.floor(max_legend_width/2)
newlabels.append(f'{l[0:half_legend_width-3]} .. {l[-half_legend_width+3:]}')
else:
newlabels.append(l)
else:
newlabels.append(textwrap.fill(l,max_legend_width))
newhandles.append(h)

if config.FITTING_PLOT_FULL_WIDTH_LEGENDS:
self.legend = ax.legend(newhandles,newlabels,loc='best', mode='expand')
else:
self.legend = ax.legend(loc='upper right', shadow=True)
if self.legend:
self.legend.set_picker(True)
self.legend = ax.legend(newhandles,newlabels,loc='best', shadow=True)
self.legend.set_picker(True)
self.legend.set_visible(self.legendVisible)

# Current labels for axes
if self.yLabel and not is_fit:
ax.set_ylabel(self.yLabel)
Expand Down Expand Up @@ -301,16 +295,6 @@ def plot(self, data=None, color=None, marker=None, hide_error=False, transform=T
# refresh canvas
self.canvas.draw_idle()

def onResize(self, event):
"""
Resize the legend window/font on canvas resize
"""
if not self.showLegend or not self.legendVisible:
return
width = _legendResize(event.width, self.parent)
# resize the legend to follow the canvas width.
if width is not None:
self.legend.prop.set_size(width)

def createContextMenu(self):
"""
Expand Down
8 changes: 8 additions & 0 deletions src/sas/system/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,15 @@ def __init__(self):
# Time out for updating sasview
self.UPDATE_TIMEOUT = 2

# If True, use an ugly but more robust legend plotting method in Fitting that results in full-
# width legends.
self.FITTING_PLOT_FULL_WIDTH_LEGENDS = False

# If True, truncates names in Fitting plot legends such that each name is maximum one line.
self.FITTING_PLOT_LEGEND_TRUNCATE = False

# sets the maximum number of characters per Fitting plot legend entry.
self.FITTING_PLOT_LEGEND_MAX_LINE_LENGTH = 30
#
# Lock the class down, this is necessary both for
# securing the class, and for setting up reading/writing files
Expand Down