mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-10 05:47:09 +01:00
Merge branch 'dougthor42-refactor-lib.plot-part3'
This commit is contained in:
@@ -2,10 +2,7 @@
|
||||
# pylint: disable=C0413
|
||||
# C0413: Import should be placed at the top of the module
|
||||
"""
|
||||
wx.lib.plot
|
||||
===========
|
||||
|
||||
This is a simple plotting library for the wxPython Phoenix project.
|
||||
A simple plotting library for the wxPython Phoenix project.
|
||||
|
||||
"""
|
||||
__version__ = "0.0.1"
|
||||
@@ -42,7 +39,7 @@ from .polyobjects import PlotGraphics
|
||||
from .polyobjects import PlotPrintout
|
||||
|
||||
from .utils import TempStyle
|
||||
from .utils import PendingDeprecation
|
||||
from .utils import pendingDeprecation
|
||||
|
||||
# For backwards compat.
|
||||
BoxPlot = PolyBoxPlot
|
||||
|
||||
@@ -28,7 +28,8 @@ except ImportError:
|
||||
imported. It probably is not installed (it's not part of the
|
||||
standard Python distribution). See the Numeric Python site
|
||||
(http://numpy.scipy.org) for information on downloading source or
|
||||
binaries."""
|
||||
binaries, or just try `pip install numpy` and it will probably
|
||||
work."""
|
||||
raise ImportError("NumPy not found.\n" + msg)
|
||||
|
||||
|
||||
@@ -509,7 +510,8 @@ class PlotDemoMainFrame(wx.Frame):
|
||||
'Enables the display of the axes values')
|
||||
|
||||
submenu = wx.Menu()
|
||||
submenu_items = ("Bottom", "Left", "Top", "Right")
|
||||
submenu_items = ("Bottom", "Left", "Top", "Right",
|
||||
"Bottom+Left", "All")
|
||||
help_txt = "Enables {} ticks"
|
||||
self.ticksSubMenu = submenu
|
||||
for _i, item in enumerate(submenu_items, 2501):
|
||||
@@ -524,6 +526,8 @@ class PlotDemoMainFrame(wx.Frame):
|
||||
self.Bind(wx.EVT_MENU, self.OnEnableTicksLeft, id=2502)
|
||||
self.Bind(wx.EVT_MENU, self.OnEnableTicksTop, id=2503)
|
||||
self.Bind(wx.EVT_MENU, self.OnEnableTicksRight, id=2504)
|
||||
self.Bind(wx.EVT_MENU, self.OnEnableTicksBottomLeft, id=2505)
|
||||
self.Bind(wx.EVT_MENU, self.OnEnableTicksAll, id=2506)
|
||||
|
||||
menu.Append(250, 'Enable Ticks', submenu,
|
||||
'Enables the display of the ticks')
|
||||
@@ -829,8 +833,8 @@ class PlotDemoMainFrame(wx.Frame):
|
||||
self.ticksSubMenu.Check(2502, self.client.enableTicks[1])
|
||||
self.ticksSubMenu.Check(2503, self.client.enableTicks[2])
|
||||
self.ticksSubMenu.Check(2504, self.client.enableTicks[3])
|
||||
# self.ticksSubMenu.Check(2505, all(self.client.enableTicks[:2]))
|
||||
# self.axesSubMenu.Check(2506, all(self.client.enableTicks))
|
||||
self.ticksSubMenu.Check(2505, all(self.client.enableTicks[:2]))
|
||||
self.ticksSubMenu.Check(2506, all(self.client.enableTicks))
|
||||
|
||||
def OnEnableTicksBottom(self, event):
|
||||
old = self.client.enableTicks
|
||||
@@ -856,6 +860,17 @@ class PlotDemoMainFrame(wx.Frame):
|
||||
old[2], event.IsChecked())
|
||||
self._checkOtherTicksMenuItems()
|
||||
|
||||
def OnEnableTicksBottomLeft(self, event):
|
||||
checked = event.IsChecked()
|
||||
old = self.client.enableTicks
|
||||
self.client.enableTicks = (checked, checked, old[2], old[3])
|
||||
self._checkOtherTicksMenuItems()
|
||||
|
||||
def OnEnableTicksAll(self, event):
|
||||
checked = event.IsChecked()
|
||||
self.client.enableTicks = tuple([checked] * 4)
|
||||
self._checkOtherTicksMenuItems()
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
### Enable AxesValues Events
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
@@ -15,7 +15,7 @@ from wx.lib import plot as wxplot
|
||||
|
||||
class PlotExample(wx.Frame):
|
||||
def __init__(self):
|
||||
wx.Frame.__init__(self, None, title="Example of wx.lib.plot")
|
||||
wx.Frame.__init__(self, None, title="Example of wx.lib.plot", size=(640,480))
|
||||
|
||||
# Generate some Data
|
||||
x_data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,9 +13,7 @@ This contains all of the PolyXXX objects used by :mod:`wx.lib.plot`.
|
||||
__docformat__ = "restructuredtext en"
|
||||
|
||||
# Standard Library
|
||||
import string as _string
|
||||
import time as _time
|
||||
import sys
|
||||
import wx
|
||||
import warnings
|
||||
from collections import namedtuple
|
||||
@@ -33,8 +31,9 @@ except:
|
||||
raise ImportError("NumPy not found.\n" + msg)
|
||||
|
||||
# Package
|
||||
from .utils import PendingDeprecation
|
||||
from .utils import pendingDeprecation
|
||||
from .utils import TempStyle
|
||||
from .utils import pairwise
|
||||
|
||||
|
||||
# XXX: Comment out this line to disable deprecation warnings
|
||||
@@ -90,13 +89,18 @@ class PolyPoints(object):
|
||||
raise ValueError("`logscale` must be a 2-tuple of bools")
|
||||
self._logscale = logscale
|
||||
|
||||
@PendingDeprecation("self.logScale property")
|
||||
def setLogScale(self, logscale):
|
||||
"""
|
||||
Set to change the axes to plot Log10(values)
|
||||
|
||||
Value must be a tuple of booleans (x_axis_bool, y_axis_bool)
|
||||
|
||||
.. deprecated:: Feb 27, 2016
|
||||
|
||||
Use the :attr:`~wx.lib.plot.polyobjects.PolyPoints.logScale`
|
||||
property instead.
|
||||
"""
|
||||
pendingDeprecation("self.logScale property")
|
||||
self._logscale = logscale
|
||||
|
||||
@property
|
||||
@@ -574,8 +578,6 @@ class PolyMarker(PolyPoints):
|
||||
'legend': ''}
|
||||
|
||||
def __init__(self, points, **attr):
|
||||
|
||||
|
||||
PolyPoints.__init__(self, points, attr)
|
||||
|
||||
def draw(self, dc, printerScale, coord=None):
|
||||
@@ -840,14 +842,6 @@ class PolyHistogram(PolyBarsBase):
|
||||
self.hist = hist
|
||||
self.binspec = binspec
|
||||
|
||||
# need to create a series of points to be used by PolyPoints
|
||||
import itertools
|
||||
def pairwise(iterable):
|
||||
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
|
||||
a, b = itertools.tee(iterable)
|
||||
next(b, None)
|
||||
return zip(a, b)
|
||||
|
||||
# define the bins and center x locations
|
||||
self.bins = list(pairwise(self.binspec))
|
||||
bar_center_x = (pair[0] + (pair[1] - pair[0])/2 for pair in self.bins)
|
||||
@@ -1013,13 +1007,13 @@ class PolyBoxPlot(PolyPoints):
|
||||
|
||||
outliers are outside of 1.5 * IQR
|
||||
|
||||
Parameters:
|
||||
-----------
|
||||
Parameters
|
||||
----------
|
||||
data : array-like
|
||||
The data to plot
|
||||
|
||||
Returns:
|
||||
--------
|
||||
Returns
|
||||
-------
|
||||
bpdata : collections.namedtuple
|
||||
Descriptive statistics for data:
|
||||
(min_data, low_whisker, q25, median, q75, high_whisker, max_data)
|
||||
@@ -1069,8 +1063,8 @@ class PolyBoxPlot(PolyPoints):
|
||||
"""
|
||||
Draws a box plot on the DC.
|
||||
|
||||
Notes:
|
||||
------
|
||||
Notes
|
||||
-----
|
||||
The following draw order is required:
|
||||
|
||||
1. First the whisker line
|
||||
@@ -1235,11 +1229,6 @@ class PlotGraphics(object):
|
||||
|
||||
@property
|
||||
def logScale(self):
|
||||
# TODO: convert to try..except statement
|
||||
# try:
|
||||
# return [obj.logScale for obj in self.objects]
|
||||
# except: # what error would be returned?
|
||||
# return
|
||||
if len(self.objects) == 0:
|
||||
return
|
||||
return [obj.logScale for obj in self.objects]
|
||||
@@ -1254,16 +1243,16 @@ class PlotGraphics(object):
|
||||
for obj in self.objects:
|
||||
obj.logScale = logscale
|
||||
|
||||
@PendingDeprecation("self.logScale property")
|
||||
def setLogScale(self, logscale):
|
||||
"""
|
||||
Set the log scale boolean value.
|
||||
|
||||
.. deprecated:: Feb 27, 2016
|
||||
|
||||
Use the :attr:`~wx.lib.plot.PlotGraphics.logScale` property
|
||||
instead.
|
||||
Use the :attr:`~wx.lib.plot.polyobjects.PlotGraphics.logScale`
|
||||
property instead.
|
||||
"""
|
||||
pendingDeprecation("self.logScale property")
|
||||
self.logScale = logscale
|
||||
|
||||
@property
|
||||
@@ -1294,88 +1283,88 @@ class PlotGraphics(object):
|
||||
for o in self.objects:
|
||||
o.scaleAndShift(scale, shift)
|
||||
|
||||
@PendingDeprecation("self.printerScale property")
|
||||
def setPrinterScale(self, scale):
|
||||
"""
|
||||
Thickens up lines and markers only for printing
|
||||
|
||||
.. deprecated:: Feb 27, 2016
|
||||
|
||||
Use the :attr:`~wx.lib.plot.PlotGraphics.printerScale` property
|
||||
instead.
|
||||
Use the :attr:`~wx.lib.plot.polyobjects.PlotGraphics.printerScale`
|
||||
property instead.
|
||||
"""
|
||||
pendingDeprecation("self.printerScale property")
|
||||
self.printerScale = scale
|
||||
|
||||
@PendingDeprecation("self.xLabel property")
|
||||
def setXLabel(self, xLabel=''):
|
||||
"""
|
||||
Set the X axis label on the graph
|
||||
|
||||
.. deprecated:: Feb 27, 2016
|
||||
|
||||
Use the :attr:`~wx.lib.plot.PlotGraphics.xLabel` property
|
||||
instead.
|
||||
"""
|
||||
Use the :attr:`~wx.lib.plot.polyobjects.PlotGraphics.xLabel`
|
||||
property instead.
|
||||
"""
|
||||
pendingDeprecation("self.xLabel property")
|
||||
self.xLabel = xLabel
|
||||
|
||||
@PendingDeprecation("self.yLabel property")
|
||||
def setYLabel(self, yLabel=''):
|
||||
"""
|
||||
Set the Y axis label on the graph
|
||||
|
||||
.. deprecated:: Feb 27, 2016
|
||||
|
||||
Use the :attr:`~wx.lib.plot.PlotGraphics.yLabel` property
|
||||
instead.
|
||||
"""
|
||||
Use the :attr:`~wx.lib.plot.polyobjects.PlotGraphics.yLabel`
|
||||
property instead.
|
||||
"""
|
||||
pendingDeprecation("self.yLabel property")
|
||||
self.yLabel = yLabel
|
||||
|
||||
@PendingDeprecation("self.title property")
|
||||
def setTitle(self, title=''):
|
||||
"""
|
||||
Set the title at the top of graph
|
||||
|
||||
.. deprecated:: Feb 27, 2016
|
||||
|
||||
Use the :attr:`~wx.lib.plot.PlotGraphics.title` property
|
||||
instead.
|
||||
Use the :attr:`~wx.lib.plot.polyobjects.PlotGraphics.title`
|
||||
property instead.
|
||||
"""
|
||||
pendingDeprecation("self.title property")
|
||||
self.title = title
|
||||
|
||||
@PendingDeprecation("self.xLabel property")
|
||||
def getXLabel(self):
|
||||
"""
|
||||
Get X axis label string
|
||||
|
||||
.. deprecated:: Feb 27, 2016
|
||||
|
||||
Use the :attr:`~wx.lib.plot.PlotGraphics.xLabel` property
|
||||
instead.
|
||||
Use the :attr:`~wx.lib.plot.polyobjects.PlotGraphics.xLabel`
|
||||
property instead.
|
||||
"""
|
||||
pendingDeprecation("self.xLabel property")
|
||||
return self.xLabel
|
||||
|
||||
@PendingDeprecation("self.yLabel property")
|
||||
def getYLabel(self):
|
||||
"""
|
||||
Get Y axis label string
|
||||
|
||||
.. deprecated:: Feb 27, 2016
|
||||
|
||||
Use the :attr:`~wx.lib.plot.PlotGraphics.yLabel` property
|
||||
instead.
|
||||
Use the :attr:`~wx.lib.plot.polyobjects.PlotGraphics.yLabel`
|
||||
property instead.
|
||||
"""
|
||||
pendingDeprecation("self.yLabel property")
|
||||
return self.yLabel
|
||||
|
||||
@PendingDeprecation("self.title property")
|
||||
def getTitle(self, title=''):
|
||||
"""
|
||||
Get the title at the top of graph
|
||||
|
||||
.. deprecated:: Feb 27, 2016
|
||||
|
||||
Use the :attr:`~wx.lib.plot.PlotGraphics.title` property
|
||||
instead.
|
||||
Use the :attr:`~wx.lib.plot.polyobjects.PlotGraphics.title`
|
||||
property instead.
|
||||
"""
|
||||
pendingDeprecation("self.title property")
|
||||
return self.title
|
||||
|
||||
@property
|
||||
@@ -1445,9 +1434,7 @@ class PlotGraphics(object):
|
||||
return self.objects[item]
|
||||
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
# Used to layout the printer page
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ __docformat__ = "restructuredtext en"
|
||||
|
||||
# Standard Library
|
||||
import functools
|
||||
import inspect
|
||||
import itertools
|
||||
from warnings import warn as _warn
|
||||
|
||||
# Third Party
|
||||
@@ -22,8 +24,9 @@ import numpy as np
|
||||
|
||||
class DisplaySide(object):
|
||||
"""
|
||||
Generic class for storing booleans describing which sides of a box are
|
||||
displayed. Used for fine-tuning the axis, ticks, and values of a graph.
|
||||
Generic class for describing which sides of a box are displayed.
|
||||
|
||||
Used for fine-tuning the axis, ticks, and values of a graph.
|
||||
|
||||
This class somewhat mimics a collections.namedtuple factory function in
|
||||
that it is an iterable and can have indiviual elements accessible by name.
|
||||
@@ -34,13 +37,13 @@ class DisplaySide(object):
|
||||
- it contains type checking, only allowing boolean values
|
||||
- it contains name checking, only allowing valid_names as attributes
|
||||
|
||||
:param bottom: Display the bottom side?
|
||||
:param bottom: Display the bottom side
|
||||
:type bottom: bool
|
||||
:param left: Display the left side?
|
||||
:param left: Display the left side
|
||||
:type left: bool
|
||||
:param top: Display the top side?
|
||||
:param top: Display the top side
|
||||
:type top: bool
|
||||
:param right: Display the right side?
|
||||
:param right: Display the right side
|
||||
:type right: bool
|
||||
"""
|
||||
# TODO: Do I want to replace with __slots__?
|
||||
@@ -108,11 +111,14 @@ class DisplaySide(object):
|
||||
return iter([self.bottom, self.left, self.top, self.right])
|
||||
|
||||
|
||||
# TODO: New name: RevertStyle? SavedStyle? Something else?
|
||||
# TODO: replace with wx.DCPenChanger/wx.DCBrushChanger, etc.
|
||||
# Alternatively, replace those with this function...
|
||||
class TempStyle(object):
|
||||
"""
|
||||
Combination Decorator and Context Manager to revert pen or brush changes
|
||||
after a method call or block finish.
|
||||
Decorator / Context Manager to revert pen or brush changes.
|
||||
|
||||
Will revert pen, brush, or both to their previous values after a method
|
||||
call or block finish.
|
||||
|
||||
:param which: The item to save and revert after execution. Can be
|
||||
one of ``{'both', 'pen', 'brush'}``.
|
||||
@@ -137,7 +143,6 @@ class TempStyle(object):
|
||||
methods**, not standard functions. There is a plan to try and remove
|
||||
this restriction, but I don't know when that will happen...
|
||||
|
||||
|
||||
.. epigraph::
|
||||
|
||||
*Combination Decorator and Context Manager! Also makes Julienne fries!
|
||||
@@ -235,51 +240,27 @@ class TempStyle(object):
|
||||
dc.SetBrush(self.prevBrush)
|
||||
|
||||
|
||||
class PendingDeprecation(object):
|
||||
def pendingDeprecation(new_func):
|
||||
"""
|
||||
Decorator which warns the developer about methods that are
|
||||
pending deprecation.
|
||||
Raise `PendingDeprecationWarning` and display a message.
|
||||
|
||||
:param new_func: The new class, method, or function that should be used.
|
||||
:type new_func: str
|
||||
|
||||
::
|
||||
|
||||
@PendingDeprecation("new_func")
|
||||
def old_func():
|
||||
pass
|
||||
|
||||
# prints the warning:
|
||||
# `old_func` is pending deprecation. Please use `new_func` instead.
|
||||
Uses inspect.stack() to determine the name of the item that this
|
||||
is called from.
|
||||
|
||||
:param new_func: The name of the function that should be used instead.
|
||||
:type new_func: string.
|
||||
"""
|
||||
_warn_txt = "`{}` is pending deprecation. Please use `{}` instead."
|
||||
|
||||
def __init__(self, new_func):
|
||||
self.new_func = new_func
|
||||
|
||||
def __call__(self, func):
|
||||
"""Support for functions"""
|
||||
self.func = func
|
||||
# self._update_docs()
|
||||
|
||||
@functools.wraps(self.func)
|
||||
def wrapper(*args, **kwargs):
|
||||
_warn(self._warn_txt.format(self.func.__name__, self.new_func),
|
||||
PendingDeprecationWarning)
|
||||
return self.func(*args, **kwargs)
|
||||
return wrapper
|
||||
|
||||
def _update_docs(self):
|
||||
""" Set the docs to that of the decorated function. """
|
||||
self.__name__ = self.func.__name__
|
||||
self.__doc__ = self.func.__doc__
|
||||
warn_txt = "`{}` is pending deprecation. Please use `{}` instead."
|
||||
_warn(warn_txt.format(inspect.stack()[1][3], new_func),
|
||||
PendingDeprecationWarning)
|
||||
|
||||
|
||||
def scale_and_shift_point(x, y, scale=1, shift=0):
|
||||
"""
|
||||
Creates a scaled and shifted 2x1 numpy array of [x, y] values.
|
||||
|
||||
The shift value must be in the scaled units.
|
||||
|
||||
:param float `x`: The x value of the unscaled, unshifted point
|
||||
:param float `y`: The y valye of the unscaled, unshifted point
|
||||
:param np.array `scale`: The scale factor to use ``[x_sacle, y_scale]``
|
||||
@@ -290,6 +271,7 @@ def scale_and_shift_point(x, y, scale=1, shift=0):
|
||||
:rtype: np.array
|
||||
|
||||
.. note::
|
||||
|
||||
:math:`new = (scale * old) + shift`
|
||||
"""
|
||||
point = scale * np.array([x, y]) + shift
|
||||
@@ -298,8 +280,7 @@ def scale_and_shift_point(x, y, scale=1, shift=0):
|
||||
|
||||
def set_displayside(value):
|
||||
"""
|
||||
Wrapper around :class:`~wx.lib.plot._DisplaySide` that allowing for
|
||||
"overloaded" calls.
|
||||
Wrapper around :class:`~wx.lib.plot._DisplaySide` that allows for "overloaded" calls.
|
||||
|
||||
If ``value`` is a boolean: all 4 sides are set to ``value``
|
||||
|
||||
@@ -333,5 +314,11 @@ def set_displayside(value):
|
||||
return DisplaySide(*_value)
|
||||
|
||||
|
||||
def pairwise(iterable):
|
||||
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
|
||||
a, b = itertools.tee(iterable)
|
||||
next(b, None)
|
||||
return zip(a, b)
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise RuntimeError("This module is not intended to be run by itself.")
|
||||
|
||||
Reference in New Issue
Block a user