Merge branch 'master' into docs-add-wx-prefix

This commit is contained in:
Robin Dunn
2016-06-03 16:44:40 -07:00
3 changed files with 313 additions and 20 deletions

View File

@@ -26,13 +26,9 @@ class TestPanel(wx.Panel):
# Create some controls
try:
backend = ""
if 'wxMSW' in wx.PlatformInfo:
# the default backend doesn't always send the EVT_MEDIA_LOADED
# event which we depend upon, so use a different backend by
# default for this demo.
backend = wx.media.MEDIABACKEND_QUICKTIME
backend = "" # let MediaCtrl choose default backend
#backend=wx.media.MEDIABACKEND_DIRECTSHOW
#backend=wx.media.MEDIABACKEND_WMP10
self.mc = wx.media.MediaCtrl()
ok = self.mc.Create(self, style=wx.SIMPLE_BORDER,
szBackend=backend)
@@ -42,6 +38,9 @@ class TestPanel(wx.Panel):
self.Destroy()
raise
# the following event is not sent with the Windows default backend
# MEDIABACKEND_DIRECTSHOW
# choose above e.g. MEDIABACKEND_WMP10 if this is a problem for you
self.Bind(wx.media.EVT_MEDIA_LOADED, self.OnMediaLoaded)
btn1 = wx.Button(self, -1, "Load File")
@@ -100,15 +99,17 @@ class TestPanel(wx.Panel):
def DoLoadFile(self, path):
self.playBtn.Disable()
if not self.mc.Load(path):
wx.MessageBox("Unable to load %s: Unsupported format?" % path,
"ERROR",
wx.ICON_ERROR | wx.OK)
self.playBtn.Disable()
else:
self.mc.SetInitialSize()
self.GetSizer().Layout()
self.slider.SetRange(0, self.mc.Length())
self.playBtn.Enable()
def OnMediaLoaded(self, evt):
self.playBtn.Enable()

View File

@@ -87,6 +87,12 @@ def run():
c.piBases = ['wx.Object']
c.find('GetEncoding').ignore()
c.find('SetEncoding').ignore()
c.find('AppendToProlog.node').transfer = True
c.find('DetachDocumentNode').transferBack = True
c.find('DetachRoot').transferBack = True
c.find('SetDocumentNode.node').transfer = True
c.find('SetRoot.node').transfer = True
#-----------------------------------------------------------------

View File

@@ -78,6 +78,14 @@
# - Added contect manager and decorator that gets and resets the pen before
# and after a function call
# - updated demo for new features
#
# May 27, 2016 Douglas Thor (doug.thor@gmail.com)
# - Added PolyBars and PolyHistogram classes
# - General Cleanup
# - Added demos for PolyBars and PolyHistogram
# - updated plotNN menu items status-bar text to be descriptive.
# - increased default size of demo
# - updated XSpec and YSpec to accept a list or tuple of (min, max) values.
"""
This is a simple light weight plotting module that can be used with
@@ -890,6 +898,219 @@ class PolyMarker(PolyPoints):
dc.DrawLineList(lines.astype(np.int32))
class PolyBars(PolyPoints):
"""
Rectangles!
"""
_attributes = {'edgecolour': 'black',
'edgewidth': 2,
'edgestyle': wx.PENSTYLE_SOLID,
'legend': '',
'fillcolour': 'red',
'fillstyle': wx.BRUSHSTYLE_SOLID,
'barwidth': None
}
def __init__(self, points, **attr):
"""
Creates PolyRectangle object
:param `points`: sequence (array, tuple or list) of (x, y) points
that define the bar.
x: the centerline of the bar.
y: the value of the bar (from y=0)
:keyword `attr`: keyword attributes, default to:
================================= ================================
'edgecolour' = 'black' wx.Pen Colour: any wx.Colour
'edgewidth' = 1 wx.Pen width
'edgestyle' = wx.PENSTYLE_SOLID wx.Pen style
'legend' = '' Line Legend to display
'fillcolour' = 'red' wx.Brush fill color: any wx.Colour
'fillstyle' = wx.BRUSHSTYLE_SOLID The fill style for the rectangle
'barwidth' = None The bar width. None means 0 space
between bars
================================= ================================
"""
PolyPoints.__init__(self, points, attr)
def _scaleAndShift(self, data, scale=(1, 1), shift=(0, 0)):
"""same as override method, but retuns a value."""
scaled = scale * data + shift
return scaled
def draw(self, dc, printerScale, coord=None):
""" Draw the bars """
pencolour = self.attributes['edgecolour']
penwidth = self.attributes['edgewidth'] * printerScale * self._pointSize[0]
penstyle = self.attributes['edgestyle']
fillcolour = self.attributes['fillcolour']
fillstyle = self.attributes['fillstyle']
barwidth = self.attributes['barwidth']
barwidth = 1.
if not isinstance(pencolour, wx.Colour):
pencolour = wx.Colour(pencolour)
pen = wx.Pen(pencolour, penwidth, penstyle)
pen.SetCap(wx.CAP_BUTT)
if not isinstance(fillcolour, wx.Colour):
fillcolour = wx.Colour(fillcolour)
brush = wx.Brush(fillcolour, fillstyle)
dc.SetPen(pen)
dc.SetBrush(brush)
if coord is None:
rects = []
if isinstance(barwidth, (int, float)):
pts = ((x, y, barwidth) for x, y in self.points)
else:
pts = ((x, y, w) for (x, y), w in zip(self.points, barwidth))
for x, y, w in pts:
# Change the point to a format that works for _scaleAndShift
rect = [[x - w / 2, y], # left, top
[x + w / 2, 0]] # right, bottom
# Scale the points to the plot area
rect = self._scaleAndShift(rect,
self.currentScale,
self.currentShift)
# Convert to (left, top, width, height)
rect = [rect[0][0], # X (left)
rect[0][1], # Y (top)
rect[1][0] - rect[0][0], # Width
rect[1][1] - rect[0][1]] # Height
rects.append(rect)
dc.DrawRectangleList(rects)
else:
dc.DrawLines(coord) # draw legend line
def getSymExtent(self, printerScale):
"""Width and Height of Marker"""
h = self.attributes['edgewidth'] * printerScale * self._pointSize[0]
w = 5 * h
return (w, h)
class PolyHistogram(PolyPoints):
"""
Histogram
Special PolyBars where the bars span the binspec.
"""
_attributes = {'edgecolour': 'black',
'edgewidth': 3,
'edgestyle': wx.PENSTYLE_SOLID,
'legend': '',
'fillcolour': wx.GREEN,
'fillstyle': wx.BRUSHSTYLE_SOLID,
}
def __init__(self, hist, binspec, **attr):
"""
Creates PolyHistogram object
:param `hist`: sequence (array, tuple or list) of y values
that define the heights of the bars (same as 1st
returned parameter from ``np.histogram(data)``).
:param `binspec`: sequence of x values that define the edges of the
bins (same as 2nd returned parameter from
``np.histogram(data)``).
len(binspec) must equal len(hist) + 1
:keyword `attr`: keyword attributes, default to:
================================= ================================
'edgecolour' = 'black' wx.Pen Colour: any wx.Colour
'edgewidth' = 3 wx.Pen width
'edgestyle' = wx.PENSTYLE_SOLID wx.Pen style
'legend' = '' Line Legend to display
'fillcolour' = 'blue' wx.Brush fill color: any wx.Colour
'fillstyle' = wx.BRUSHSTYLE_SOLID The fill style for the rectangle
================================= ================================
"""
if len(binspec) != len(hist) + 1:
raise ValueError("Length of binspec must = length of hist + 1")
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)
self.bins = list(pairwise(self.binspec))
x = []
for pair in self.bins:
x.append(pair[0] + (pair[1] - pair[0])/2)
points = list(zip(x, self.hist))
PolyPoints.__init__(self, points, attr)
def _scaleAndShift(self, data, scale=(1, 1), shift=(0, 0)):
"""same as override method, but retuns a value."""
scaled = scale * data + shift
return scaled
def draw(self, dc, printerScale, coord=None):
""" Draw the bars """
pencolour = self.attributes['edgecolour']
penwidth = self.attributes['edgewidth'] * printerScale * self._pointSize[0]
penstyle = self.attributes['edgestyle']
fillcolour = self.attributes['fillcolour']
fillstyle = self.attributes['fillstyle']
if not isinstance(pencolour, wx.Colour):
pencolour = wx.Colour(pencolour)
pen = wx.Pen(pencolour, penwidth, penstyle)
pen.SetCap(wx.CAP_BUTT)
if not isinstance(fillcolour, wx.Colour):
fillcolour = wx.Colour(fillcolour)
brush = wx.Brush(fillcolour, fillstyle)
dc.SetPen(pen)
dc.SetBrush(brush)
if coord is None:
rects = []
for y, (low, high) in zip(self.hist, self.bins):
# Change the point to a format that works for _scaleAndShift
rect = [[low, y], # left, top
[high, 0]] # right, bottom
# Scale the points to the plot area
rect = self._scaleAndShift(rect,
self.currentScale,
self.currentShift)
# Convert to (left, top, width, height)
rect = [rect[0][0], # X (left)
rect[0][1], # Y (top)
rect[1][0] - rect[0][0], # Width
rect[1][1] - rect[0][1]] # Height
rects.append(rect)
dc.DrawRectangleList(rects)
else:
dc.DrawLines(coord) # draw legend line
def getSymExtent(self, printerScale):
"""Width and Height of Marker"""
h = self.attributes['edgewidth'] * printerScale * self._pointSize[0]
w = 5 * h
return (w, h)
class BoxPlot(PolyPoints):
"""
Class to contain box plots
@@ -3850,9 +4071,9 @@ def _draw8Objects():
Box plot
"""
data1 = np.array([912, 337, 607, 583, 512, 531, 558, 381, 621, 574,
538, 577, 679, 415, 454, 417, 635, 319, 350, 183,
863, 337, 607, 583, 512, 531, 558, 381, 621, 574,
538, 577, 679, 415, 454, 417, 635, 319, 350, 97])
538, 577, 679, 415, 454, 417, 635, 319, 350, 183,
863, 337, 607, 583, 512, 531, 558, 381, 621, 574,
538, 577, 679, 415, 454, 417, 635, 319, 350, 97])
data2 = np.array([912, 337, 607, 583, 512, 531, 558, 381, 621, 574,
538, 532, 829, 82, 454, 417, 635, 319, 350, 183,
863, 337, 607, 583, 512, 531, 558, 866, 621, 574,
@@ -3874,11 +4095,52 @@ def _draw8Objects():
"",
"Value")
def _draw9Objects():
"""
Histogram
The following must be true:
len(bspec) = len(hist_data) + 1
"""
data = 2.25 * np.random.randn(50) + 3
heights, bins = np.histogram(data, bins=10)
hist_fixed_binsize = PolyHistogram(heights, bins)
# Bins can also be arbitrary widths:
hist_variable_binsize = PolyHistogram(
[2, 3, 4, 6, 3],
[18, 19, 22, 25, 26, 27],
fillcolour=wx.BLUE,
edgewidth=2,
edgecolour=wx.RED,
)
return PlotGraphics(
[hist_fixed_binsize, hist_variable_binsize],
"Histogram with fixed binsize (left) and variable binsize (right)",
"Value",
"Count",
)
def _draw10Objects():
"""
A real bar graph
"""
bar_height = np.array([1, 5, 8, 16, 12, 15, 18, 23, 4, 7, 9, 6])
bar_location = np.array([0, 2, 4, 6, 8, 10, 11, 12, 16, 20, 30])
data = list(zip(bar_location, bar_height))
bars = [PolyBars(data)]
return PlotGraphics(bars, "Histogram", "XValue", "Count")
class TestFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title,
wx.DefaultPosition, (600, 400))
wx.DefaultPosition, (800, 600))
# Now Create the menu bar and items
self.mainmenu = wx.MenuBar()
@@ -3903,22 +4165,36 @@ class TestFrame(wx.Frame):
### "Plot" Menu Items ###############################################
# -------------------------------------------------------------------
menu = wx.Menu()
menu.Append(206, 'Draw1 - sin, cos', 'Draw plots1')
menu.Append(206, 'Draw1 - sin, cos',
'Draw Sin and Cos curves')
self.Bind(wx.EVT_MENU, self.OnPlotDraw1, id=206)
menu.Append(207, 'Draw2 - sin, cos, large joined markers', 'Draw plots2')
menu.Append(207, 'Draw2 - sin, cos, large joined markers',
'Draw Sin and Cos curves with some large joined makers')
self.Bind(wx.EVT_MENU, self.OnPlotDraw2, id=207)
menu.Append(208, 'Draw3 - various markers', 'Draw plots3')
menu.Append(208, 'Draw3 - various markers',
'Demo various markers')
self.Bind(wx.EVT_MENU, self.OnPlotDraw3, id=208)
menu.Append(209, 'Draw4 - 25k pts', 'Draw plots4')
menu.Append(209, 'Draw4 - 25k pts',
'Example of drawing many points quickly')
self.Bind(wx.EVT_MENU, self.OnPlotDraw4, id=209)
menu.Append(210, 'Draw5 - empty plot', 'Draw plots5')
menu.Append(210, 'Draw5 - empty plot',
'An empty plot')
self.Bind(wx.EVT_MENU, self.OnPlotDraw5, id=210)
menu.Append(260, 'Draw6 - bar graph', 'Draw plots6')
menu.Append(260, 'Draw6 - fake bar graph via lines',
'Fake a bar graph by using lines.')
self.Bind(wx.EVT_MENU, self.OnPlotDraw6, id=260)
menu.Append(261, 'Draw7 - log-log', 'Draw plots7')
menu.Append(261, 'Draw7 - log-log',
'Plot a Log-Log graph')
self.Bind(wx.EVT_MENU, self.OnPlotDraw7, id=261)
menu.Append(262, 'Draw8 - Box Plots', 'Draw plots8')
menu.Append(262, 'Draw8 - Box Plots',
'Show off some box plots')
self.Bind(wx.EVT_MENU, self.OnPlotDraw8, id=262)
menu.Append(263, 'Draw9 - Histogram',
'Plot a histogram')
self.Bind(wx.EVT_MENU, self.OnPlotDraw9, id=263)
menu.Append(264, 'Draw10 - real bar graph',
'Plot a real bar chart (not faked with lines)')
self.Bind(wx.EVT_MENU, self.OnPlotDraw10, id=264)
menu.AppendSeparator()
@@ -4259,6 +4535,16 @@ class TestFrame(wx.Frame):
self.resetDefaults()
self.client.Draw(_draw8Objects())
def OnPlotDraw9(self, event):
"""Histogram example"""
self.resetDefaults()
self.client.Draw(_draw9Objects())
def OnPlotDraw10(self, event):
"""Bar Chart example"""
self.resetDefaults()
self.client.Draw(_draw10Objects())
def OnPlotRedraw(self, event):
self.client.Redraw()