Moved Title and Label drawing to separate methods

+ changed instances of time.clock to time.perf_counter (Python 3.3+)
+ Moved drawing of plot title and axes label to separate methods
+ Made drawing of axes labels a attribute of PlotCanvas.
+ Added ability to turn axes labels or plot title on and off individually
  + Added demo for this
This commit is contained in:
Douglas Thor
2015-08-03 22:26:39 -07:00
parent 0ad2d04874
commit 5cb14aa820

View File

@@ -216,6 +216,7 @@ class PendingDeprecation(object):
def __call__(self, func):
"""Support for functions"""
self.func = func
self._update_docs()
@functools.wraps(self.func)
def wrapper(*args, **kwargs):
@@ -224,6 +225,10 @@ class PendingDeprecation(object):
return self.func(*args, **kwargs)
return wrapper
def _update_docs(self):
self.__name__ = self.func.__name__
self.__doc__ = self.func.__doc__
#
# Plotting classes...
@@ -710,11 +715,10 @@ class PlotGraphics(object):
def draw(self, dc):
for o in self.objects:
# t=_time.clock() # profile info
# t=_time.perf_counter() # profile info
o._pointSize = self._pointSize
o.draw(dc, self._printerScale)
#dt= _time.clock()-t
#print(o, "time=", dt)
# print(o, "time=", _time.perf_counter()-t)
def getSymExtent(self, printerScale):
"""Get max width and height of lines and markers symbols for legend"""
@@ -837,6 +841,9 @@ class PlotCanvas(wx.Panel):
self._gridEnabled = False
self._legendEnabled = False
self._titleEnabled = True
self._xAxisLabelEnabled = True
self._yAxisLabelEnabled = True
self._axesLabelsEnabled = True
self._centerLinesEnabled = False
self._diagonalsEnabled = False
self._ticksEnabled = False
@@ -1596,6 +1603,50 @@ class PlotCanvas(wx.Panel):
self._ticksEnabled = value
self.Redraw()
@property
def EnablePlotTitle(self):
return self._titleEnabled
@EnablePlotTitle.setter
def EnablePlotTitle(self, value):
if not isinstance(value, bool):
raise TypeError("`value` must be boolean True or False")
self._titleEnabled = value
self.Redraw()
@property
def EnableXAxisLabel(self):
return self._xAxisLabelEnabled
@EnableXAxisLabel.setter
def EnableXAxisLabel(self, value):
if not isinstance(value, bool):
raise TypeError("`value` must be boolean True or False")
self._xAxisLabelEnabled = value
self.Redraw()
@property
def EnableYAxisLabel(self):
return self._yAxisLabelEnabled
@EnableYAxisLabel.setter
def EnableYAxisLabel(self, value):
if not isinstance(value, bool):
raise TypeError("`value` must be boolean True or False")
self._yAxisLabelEnabled = value
self.Redraw()
@property
def EnableAxesLabels(self):
return self._axesLabelsEnabled
@EnableAxesLabels.setter
def EnableAxesLabels(self, value):
if not isinstance(value, bool):
raise TypeError("`value` must be boolean True or False")
self._axesLabelsEnabled = value
self.Redraw()
@PendingDeprecation("self.PointLabelFunc property")
def SetPointLabelFunc(self, func):
"""Sets the function with custom code for pointLabel drawing
@@ -1954,23 +2005,9 @@ class PlotCanvas(wx.Panel):
# shift plot area by this amount
textSize_shift = np.array([lhsW, bottomH])
# draw title if requested
if self._titleEnabled:
dc.SetFont(self._getFont(self._fontSizeTitle))
titlePos = (self.plotbox_origin[0] + lhsW + (self.plotbox_size[0] - lhsW - rhsW) / 2. - titleWH[0] / 2.,
self.plotbox_origin[1] - self.plotbox_size[1])
dc.DrawText(graphics.Title, titlePos[0], titlePos[1])
# draw label text
dc.SetFont(self._getFont(self._fontSizeAxis))
xLabelPos = (self.plotbox_origin[0] + lhsW + (self.plotbox_size[0] - lhsW - rhsW) / 2. - xLabelWH[0] / 2.,
self.plotbox_origin[1] - xLabelWH[1])
dc.DrawText(graphics.XLabel, xLabelPos[0], xLabelPos[1])
yLabelPos = (self.plotbox_origin[0] - 3 * self._pointSize[0],
self.plotbox_origin[1] - bottomH - (self.plotbox_size[1] - bottomH - topH) / 2. + yLabelWH[0] / 2.)
if graphics.YLabel: # bug fix for Linux
dc.DrawRotatedText(
graphics.YLabel, yLabelPos[0], yLabelPos[1], 90)
# Draw the labels (title, axes labels)
self._drawPlotAreaLabels(dc, graphics, lhsW, rhsW, titleWH,
bottomH, topH, xLabelWH, yLabelWH)
# drawing legend makers and text
if self._legendEnabled:
@@ -2004,9 +2041,9 @@ class PlotCanvas(wx.Panel):
rectWidth * self._pointSize[0] + 2,
rectHeight * self._pointSize[1] + 1)
# Draw the lines and markers
#start = _time.clock()
# start = _time.perf_counter()
graphics.draw(dc)
# print("entire graphics drawing took: %f second"%(_time.clock() - start))
# print("entire graphics drawing took: %f second"%(_time.perf_counter() - start))
# remove the clipping region
dc.DestroyClippingRegion()
@@ -2445,6 +2482,7 @@ class PlotCanvas(wx.Panel):
# TODO: rename TickLength - these aren't ticks anymore
# TODO: figure out if I can remove this calculation stuff.
# replace with something like XMaxRange, YMaxRange
x, y, width, height = self._point2ClientCoord(p1, p2)
if self._gridEnabled == 'Horizontal':
yTickLength = (width / 2.0 + 1) * self._pointSize[1]
@@ -2498,15 +2536,6 @@ class PlotCanvas(wx.Panel):
pt = scale * np.array([x, y]) + shift
dc.DrawLine(pt[0], pt[1], pt[0] - d, pt[1])
# TODO: create own dc.SetPen() function?
# There is a lot of instances of:
# penWidth = self.printerScale * itemWidth
# dc.SetPen(wx.Pen(itemColour, penWidth, itemStyle)
# and it could be replaced with a simpler function call.
#
# Alternative: instead of having separate color, width, style properties
# for each graph element, just have a wx.Pen property
@SavePen
def _drawCenterLines(self, dc, p1, p2, scale, shift):
"""Draws the center lines"""
@@ -2610,6 +2639,7 @@ class PlotCanvas(wx.Panel):
pt[1] - 0.75 * h)
text = 0 # axis values not drawn on right side
@SavePen
def _drawPlotAreaItems(self, dc, p1, p2, scale, shift, xticks, yticks):
"""Draws each frame element"""
if self._ticksEnabled:
@@ -2630,9 +2660,37 @@ class PlotCanvas(wx.Panel):
if self._axesValuesEnabled:
self._drawAxesValues(dc, p1, p2, scale, shift, xticks, yticks)
# TODO: Add this
# if self._axesLabels:
# self._drawAxesLabesl(dc, p1, p2, scale, shift, xticks, yticks)
@SavePen
def _drawPlotTitle(self, dc, graphics, lhsW, rhsW, titleWH):
"""Draws the plot title"""
# TODO: Clean up math
dc.SetFont(self._getFont(self._fontSizeTitle))
titlePos = (self.plotbox_origin[0] + lhsW + (self.plotbox_size[0] - lhsW - rhsW) / 2. - titleWH[0] / 2.,
self.plotbox_origin[1] - self.plotbox_size[1])
dc.DrawText(graphics.Title, titlePos[0], titlePos[1])
def _drawAxesLabels(self, dc, graphics, lhsW, rhsW, bottomH, topH, xLabelWH, yLabelWH):
"""Draws the axes labels"""
# TODO: axes values get big when this is turned off
# TODO: clean up math
dc.SetFont(self._getFont(self._fontSizeAxis))
xLabelPos = (self.plotbox_origin[0] + lhsW + (self.plotbox_size[0] - lhsW - rhsW) / 2. - xLabelWH[0] / 2.,
self.plotbox_origin[1] - xLabelWH[1])
dc.DrawText(graphics.XLabel, xLabelPos[0], xLabelPos[1])
yLabelPos = (self.plotbox_origin[0] - 3 * self._pointSize[0],
self.plotbox_origin[1] - bottomH - (self.plotbox_size[1] - bottomH - topH) / 2. + yLabelWH[0] / 2.)
if graphics.YLabel: # bug fix for Linux
dc.DrawRotatedText(
graphics.YLabel, yLabelPos[0], yLabelPos[1], 90)
@SavePen
def _drawPlotAreaLabels(self, dc, graphics, lhsW, rhsW, titleWH, bottomH, topH, xLabelWH, yLabelWH):
# TODO: clean up call signature.
if self._titleEnabled:
self._drawPlotTitle(dc, graphics, lhsW, rhsW, titleWH)
if self._axesLabelsEnabled:
self._drawAxesLabels(dc, graphics, lhsW, rhsW, bottomH, topH, xLabelWH, yLabelWH)
def _xticks(self, *args):
if self._logscale[0]:
@@ -3163,6 +3221,16 @@ class TestFrame(wx.Frame):
'Enables the display of the ticks', kind=wx.ITEM_CHECK)
self.Bind(wx.EVT_MENU, self.OnEnableTicks, id=250)
menu.Append(255, 'Enable Plot Title',
'Enables the plot title', kind=wx.ITEM_CHECK)
self.Bind(wx.EVT_MENU, self.OnEnablePlotTitle, id=255)
menu.Check(255, True)
menu.Append(270, 'Enable Axes Labels',
'Enables the X and Y axes labels', kind=wx.ITEM_CHECK)
self.Bind(wx.EVT_MENU, self.OnEnableAxesLabels, id=270)
menu.Check(270, True)
self.mainmenu.Append(menu, '&Plot')
menu = wx.Menu()
@@ -3177,7 +3245,8 @@ class TestFrame(wx.Frame):
self.client = PlotCanvas(self)
# define the function for drawing pointLabels
self.client.SetPointLabelFunc(self.DrawPointLabel)
# self.client.SetPointLabelFunc(self.DrawPointLabel)
self.client.PointLabelFunc = self.DrawPointLabel
# Create mouse event for showing cursor coords in status bar
self.client.canvas.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
# Show closest point when enabled
@@ -3279,10 +3348,10 @@ class TestFrame(wx.Frame):
drawObj = _draw4Objects()
self.client.Draw(drawObj)
# profile
## start = _time.clock()
# start = _time.perf_counter()
# for x in range(10):
# self.client.Draw(drawObj)
## print("10 plots of Draw4 took: %f sec."%(_time.clock() - start))
## print("10 plots of Draw4 took: %f sec."%(_time.perf_counter() - start))
# profile end
def OnPlotDraw5(self, event):
@@ -3353,6 +3422,12 @@ class TestFrame(wx.Frame):
def OnEnableAxesValues(self, event):
self.client.EnableAxesValues = event.IsChecked()
def OnEnablePlotTitle(self, event):
self.client.EnablePlotTitle = event.IsChecked()
def OnEnableAxesLabels(self, event):
self.client.EnableAxesLabels = event.IsChecked()
def OnEnableCenterLines(self, event):
self.client.EnableCenterLines = event.IsChecked()