Skip to content

Commit 4e97b0b

Browse files
committed
Line plot: Customizable labels
1 parent 7c163dc commit 4e97b0b

File tree

2 files changed

+77
-3
lines changed

2 files changed

+77
-3
lines changed

Orange/widgets/visualize/owlineplot.py

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
from Orange.widgets.utils.widgetpreview import WidgetPreview
2828
from Orange.widgets.utils.state_summary import format_summary_details
2929
from Orange.widgets.visualize.owdistributions import LegendItem
30+
from Orange.widgets.visualize.utils.customizableplot import FontUpdater, \
31+
BaseParameterSetter as Setter
3032
from Orange.widgets.widget import OWWidget, Input, Output, Msg
3133

3234

@@ -93,6 +95,23 @@ class LinePlotStyle:
9395

9496

9597
class LinePlotAxisItem(pg.AxisItem):
98+
def generateDrawSpecs(self, p):
99+
if self.tickFont:
100+
p.setFont(self.tickFont)
101+
return super().generateDrawSpecs(p)
102+
103+
def _updateMaxTextSize(self, x):
104+
if self.orientation in ['left', 'right']:
105+
self.textWidth = x
106+
if self.style['autoExpandTextSpace'] is True:
107+
self._updateWidth()
108+
else:
109+
self.textHeight = x
110+
if self.style['autoExpandTextSpace'] is True:
111+
self._updateHeight()
112+
113+
114+
class BottomAxisItem(LinePlotAxisItem):
96115
def __init__(self, *args, **kwargs):
97116
super().__init__(*args, **kwargs)
98117
self._ticks = {}
@@ -103,6 +122,9 @@ def set_ticks(self, ticks):
103122
def tickStrings(self, values, scale, spacing):
104123
return [self._ticks.get(v * scale, "") for v in values]
105124

125+
def boundingRect(self):
126+
return super().boundingRect().adjusted(0, 0, 0, 10)
127+
106128

107129
class LinePlotViewBox(ViewBox):
108130
selection_changed = Signal(np.ndarray)
@@ -183,16 +205,56 @@ def reset(self):
183205
self._graph_state = SELECT
184206

185207

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

198260
def _create_legend(self, anchor):
@@ -211,6 +273,8 @@ def update_legend(self, variable):
211273
dots = pg.ScatterPlotItem(pen=c, brush=c, size=10, shape="s")
212274
self.legend.addItem(dots, escape(name))
213275
self.legend.show()
276+
FontUpdater.update_legend_font(self.legend_items,
277+
**self.legend_settings)
214278

215279
def select(self, indices):
216280
keys = QApplication.keyboardModifiers()
@@ -439,6 +503,7 @@ class Outputs:
439503
selection = Setting(None, schema_only=True)
440504

441505
graph_name = "graph.plotItem"
506+
initial_visual_settings = LinePlotGraph.initial_settings
442507

443508
class Error(OWWidget.Error):
444509
not_enough_attrs = Msg("Need at least one continuous feature.")
@@ -771,6 +836,9 @@ def clear(self):
771836
def __in(obj, collection):
772837
return collection is not None and obj in collection
773838

839+
def set_visual_settings(self, *args):
840+
self.graph.set_parameter(*args)
841+
774842

775843
if __name__ == "__main__":
776844
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)