Skip to content

Commit 4ae30d6

Browse files
committed
Line plot: Customizable labels
1 parent 51f0520 commit 4ae30d6

File tree

2 files changed

+79
-3
lines changed

2 files changed

+79
-3
lines changed

Orange/widgets/visualize/owlineplot.py

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
from pyqtgraph.functions import mkPen
1212
from pyqtgraph.graphicsItems.ViewBox import ViewBox
1313

14+
from orangewidget.utils.visual_settings_dlg import VisualSettingsDialog
15+
1416
from Orange.data import Table, DiscreteVariable
1517
from Orange.data.sql.table import SqlTable
1618
from Orange.statistics.util import countnans, nanmean, nanmin, nanmax, nanstd
@@ -27,6 +29,8 @@
2729
from Orange.widgets.utils.widgetpreview import WidgetPreview
2830
from Orange.widgets.utils.state_summary import format_summary_details
2931
from Orange.widgets.visualize.owdistributions import LegendItem
32+
from Orange.widgets.visualize.utils.customizableplot import FontUpdater, \
33+
BaseParameterSetter as Setter
3034
from Orange.widgets.widget import OWWidget, Input, Output, Msg
3135

3236

@@ -93,6 +97,23 @@ class LinePlotStyle:
9397

9498

9599
class LinePlotAxisItem(pg.AxisItem):
100+
def generateDrawSpecs(self, p):
101+
if self.tickFont:
102+
p.setFont(self.tickFont)
103+
return super().generateDrawSpecs(p)
104+
105+
def _updateMaxTextSize(self, x):
106+
if self.orientation in ['left', 'right']:
107+
self.textWidth = x
108+
if self.style['autoExpandTextSpace'] is True:
109+
self._updateWidth()
110+
else:
111+
self.textHeight = x
112+
if self.style['autoExpandTextSpace'] is True:
113+
self._updateHeight()
114+
115+
116+
class BottomAxisItem(LinePlotAxisItem):
96117
def __init__(self, *args, **kwargs):
97118
super().__init__(*args, **kwargs)
98119
self._ticks = {}
@@ -103,6 +124,9 @@ def set_ticks(self, ticks):
103124
def tickStrings(self, values, scale, spacing):
104125
return [self._ticks.get(v * scale, "") for v in values]
105126

127+
def boundingRect(self):
128+
return super().boundingRect().adjusted(0, 0, 0, 10)
129+
106130

107131
class LinePlotViewBox(ViewBox):
108132
selection_changed = Signal(np.ndarray)
@@ -183,16 +207,56 @@ def reset(self):
183207
self._graph_state = SELECT
184208

185209

186-
class LinePlotGraph(pg.PlotWidget):
210+
class ParameterSetter(Setter):
211+
initial_settings = {Setter.LABELS_BOX: {
212+
Setter.FONT_FAMILY_LABEL: FontUpdater.FONT_FAMILY_SETTING,
213+
Setter.AXIS_TICKS_LABEL: FontUpdater.FONT_SETTING,
214+
Setter.LEGEND_LABEL: FontUpdater.FONT_SETTING,
215+
}}
216+
217+
def __init__(self):
218+
self.legend_settings = {}
219+
220+
def update_axes(**settings):
221+
FontUpdater.update_axes_ticks_font(self.axis_items, **settings)
222+
223+
def update_legend(**settings):
224+
self.legend_settings.update(**settings)
225+
FontUpdater.update_legend_font(self.legend_items, **settings)
226+
227+
def update_font_family(**settings):
228+
update_axes(**settings)
229+
update_legend(**settings)
230+
231+
self.setters = {self.LABELS_BOX: {
232+
self.FONT_FAMILY_LABEL: update_font_family,
233+
self.AXIS_TICKS_LABEL: update_axes,
234+
self.LEGEND_LABEL: update_legend,
235+
}}
236+
237+
@property
238+
def axis_items(self):
239+
return [value["item"] for value in self.getPlotItem().axes.values()]
240+
241+
@property
242+
def legend_items(self):
243+
return self.legend.items
244+
245+
246+
# Customizable plot widget
247+
class LinePlotGraph(pg.PlotWidget, ParameterSetter):
187248
def __init__(self, parent):
188-
self.bottom_axis = LinePlotAxisItem(orientation="bottom")
249+
self.bottom_axis = BottomAxisItem(orientation="bottom")
250+
left_item = LinePlotAxisItem(orientation="left")
189251
super().__init__(parent, viewBox=LinePlotViewBox(),
190252
background="w", enableMenu=False,
191-
axisItems={"bottom": self.bottom_axis})
253+
axisItems={"bottom": self.bottom_axis,
254+
"left": left_item})
192255
self.view_box = self.getViewBox()
193256
self.selection = set()
194257
self.legend = self._create_legend(((1, 0), (1, 0)))
195258
self.getPlotItem().buttonsHidden = True
259+
self.getPlotItem().setContentsMargins(5, 0, 0, 10)
196260
self.setRenderHint(QPainter.Antialiasing, True)
197261

198262
def _create_legend(self, anchor):
@@ -211,6 +275,8 @@ def update_legend(self, variable):
211275
dots = pg.ScatterPlotItem(pen=c, brush=c, size=10, shape="s")
212276
self.legend.addItem(dots, escape(name))
213277
self.legend.show()
278+
FontUpdater.update_legend_font(self.legend_items,
279+
**self.legend_settings)
214280

215281
def select(self, indices):
216282
keys = QApplication.keyboardModifiers()
@@ -463,6 +529,7 @@ def __init__(self, parent=None):
463529
self.graph_variables = []
464530
self.setup_gui()
465531

532+
VisualSettingsDialog(self, LinePlotGraph.initial_settings)
466533
self.graph.view_box.selection_changed.connect(self.selection_changed)
467534
self.enable_selection.connect(self.graph.view_box.enable_selection)
468535

@@ -771,6 +838,9 @@ def clear(self):
771838
def __in(obj, collection):
772839
return collection is not None and obj in collection
773840

841+
def set_visual_settings(self, *args):
842+
self.graph.set_parameter(*args)
843+
774844

775845
if __name__ == "__main__":
776846
data = Table("brown-selected")

Orange/widgets/visualize/tests/test_owlineplot.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,12 @@ def test_summary(self):
306306
self.assertEqual(info._StateInfo__output_summary.brief, "")
307307
self.assertEqual(info._StateInfo__output_summary.details, no_output)
308308

309+
def test_scalable_axis_item(self):
310+
from pyqtgraph import __version__
311+
# When upgraded to 0.11.1 check if resizing AxisItem font size works
312+
# and LinePlotAxisItem functionality can be removed.
313+
self.assertLess(__version__, "0.11.1")
314+
309315

310316
class TestSegmentsIntersection(unittest.TestCase):
311317
def test_ccw(self):

0 commit comments

Comments
 (0)