📄 wxpyplot.py
字号:
self.SetBackgroundColour(wx.wxNamedColour("white"))
wx.EVT_PAINT(self, self.OnPaint)
wx.EVT_SIZE(self,self.OnSize)
#Create some mouse events for zooming
wx.EVT_LEFT_DOWN(self, self.OnMouseLeftDown)
wx.EVT_LEFT_UP(self, self.OnMouseLeftUp)
wx.EVT_MOTION(self, self.OnMotion)
wx.EVT_LEFT_DCLICK(self, self.OnMouseDoubleClick)
wx.EVT_RIGHT_DOWN(self, self.OnMouseRightDown)
# set curser as cross-hairs
self.SetCursor(wx.wxCROSS_CURSOR)
#Things for printing
self.print_data = wx.wxPrintData()
self.print_data.SetPaperId(wx.wxPAPER_LETTER)
self.print_data.SetOrientation(wx.wxLANDSCAPE)
self.pageSetupData= wx.wxPageSetupDialogData()
self.pageSetupData.SetMarginBottomRight((25,25))
self.pageSetupData.SetMarginTopLeft((25,25))
self.pageSetupData.SetPrintData(self.print_data)
self.printerScale = 1
self.parent= parent
#Zooming variables
self._zoomInFactor = 0.5
self._zoomOutFactor = 2
self._zoomCorner1= scipy.array([0.0, 0.0]) #left mouse down corner
self._zoomCorner2= scipy.array([0.0, 0.0]) #left mouse up corner
self._zoomEnabled= False
self._hasDragged= False
#Drawing Variables
self.last_draw = None
self.original_draw = None
self._pointScale= 1
self._pointShift= 0
self._xSpec= 'auto'
self._ySpec= 'auto'
self._gridEnabled= False
self._legendEnabled= False
self._legendItems = None
#Fonts
self._fontCache = {}
self._fontSizeAxis= 10
self._fontSizeTitle= 15
self._fontSizeLegend= 7
# OnSize called to make sure the buffer is initialized.
# This might result in OnSize getting called twice on some
# platforms at initialization, but little harm done.
self.OnSize(None) #sets the initial size based on client size
#SaveFile
wx.wxInitAllImageHandlers()
def SaveFile(self, fileName= ''):
"""Saves the file to the type specified in the extension. If no file
name is specified a dialog box is provided. Returns True if sucessful,
otherwise False.
.bmp Save a Windows bitmap file.
.xbm Save an X bitmap file.
.xpm Save an XPM bitmap file.
.png Save a Portable Network Graphics file.
.jpg Save a Joint Photographic Experts Group file.
"""
if string.lower(fileName[-3:]) not in ['bmp','xbm','xpm','png','jpg']:
dlg1 = wx.wxFileDialog(self, "Choose a file with extension bmp, gif, xbm, xpm, png, or jpg", ".", "",
"BMP files (*.bmp)|*.bmp|XBM files (*.xbm)|*.xbm|XPM file (*.xpm)|*.xpm|PNG files (*.png)|*.png|JPG files (*.jpg)|*.jpg",
wx.wxSAVE|wx.wxOVERWRITE_PROMPT)
try:
while 1:
if dlg1.ShowModal() == wx.wxID_OK:
fileName = dlg1.GetPath()
#Check for proper exension
if string.lower(fileName[-3:]) not in ['bmp','xbm','xpm','png','jpg']:
dlg2 = wx.wxMessageDialog(self, 'File name extension\n'
'must be one of\n'
'bmp, xbm, xpm, png, or jpg',
'File Name Error', wx.wxOK | wx.wxICON_ERROR)
try:
dlg2.ShowModal()
finally:
dlg2.Destroy()
else:
break #now save file
else: #exit without saving
return False
finally:
dlg1.Destroy()
#File name has required extension
fType = string.lower(fileName[-3:])
if fType == "bmp":
tp= wx.wxBITMAP_TYPE_BMP #Save a Windows bitmap file.
elif fType == "xbm":
tp= wx.wxBITMAP_TYPE_XBM #Save an X bitmap file.
elif fType == "xpm":
tp= wx.wxBITMAP_TYPE_XPM #Save an XPM bitmap file.
elif fType == "jpg":
tp= wx.wxBITMAP_TYPE_JPEG #Save a JPG file.
else:
tp= wx.wxBITMAP_TYPE_PNG #Save a PNG file.
#Save Bitmap
res= self._Buffer.SaveFile(fileName, tp)
return res
def PageSetup(self):
"""Brings up the page setup dialog"""
data = self.pageSetupData
data.SetPrintData(self.print_data)
dlg = wx.wxPageSetupDialog(self.parent, data)
try:
if dlg.ShowModal() == wx.wxID_OK:
data = dlg.GetPageSetupData() #returns wxPageSetupDialogData
#updates page parameters from dialog
self.pageSetupData.SetMarginBottomRight(data.GetMarginBottomRight())
self.pageSetupData.SetMarginTopLeft(data.GetMarginTopLeft())
self.pageSetupData.SetPrintData(data.GetPrintData())
self.print_data=data.GetPrintData() #updates print_data
finally:
dlg.Destroy()
def Printout(self, paper=None):
"""Print current plot."""
if paper != None:
self.print_data.SetPaperId(paper)
pdd = wx.wxPrintDialogData()
pdd.SetPrintData(self.print_data)
printer = wx.wxPrinter(pdd)
out = plot_printout(self)
print_ok = printer.Print(self.parent, out)
if print_ok:
self.print_data = printer.GetPrintDialogData().GetPrintData()
out.Destroy()
def PrintPreview(self):
"""Print-preview current plot."""
printout = plot_printout(self)
printout2 = plot_printout(self)
self.preview = wx.wxPrintPreview(printout, printout2, self.print_data)
if not self.preview.Ok():
wx.wxMessageDialog(self, "Print Preview failed.\n" \
"Check that default printer is configured\n", \
"Print error", wx.wxOK|wx.wxCENTRE).ShowModal()
self.preview.SetZoom(30)
#search up tree to find frame instance
frameInst= self
while not isinstance(frameInst, wx.wxFrame):
frameInst= frameInst.GetParent()
frame = wx.wxPreviewFrame(self.preview, frameInst, "Preview")
frame.Initialize()
frame.SetPosition(self.GetPosition())
frame.SetSize((500,400))
frame.Centre(wx.wxBOTH)
frame.Show(True)
def SetFontSizeAxis(self, point= 10):
"""Set the tick and axis label font size (default is 10 point)"""
self._fontSizeAxis= point
def GetFontSizeAxis(self):
"""Get current tick and axis label font size in points"""
return self._fontSizeAxis
def SetFontSizeTitle(self, point= 15):
"""Set Title font size (default is 15 point)"""
self._fontSizeTitle= point
def GetFontSizeTitle(self):
"""Get current Title font size in points"""
return self._fontSizeTitle
def SetFontSizeLegend(self, point= 7):
"""Set Legend font size (default is 7 point)"""
self._fontSizeLegend= point
def GetFontSizeLegend(self):
"""Get current Legend font size in points"""
return self._fontSizeLegend
def SetEnableZoom(self, value):
"""Set True to enable zooming."""
if value not in [True,False]:
raise TypeError, "Value should be True or False"
self._zoomEnabled= value
def GetEnableZoom(self):
"""True if zooming enabled."""
return self._zoomEnabled
def SetEnableGrid(self, value):
"""Set True to enable grid."""
if value not in [True,False]:
raise TypeError, "Value should be True or False"
self._gridEnabled= value
self.Redraw()
def GetEnableGrid(self):
"""True if grid enabled."""
return self._gridEnabled
def SetEnableLegend(self, value):
"""Set True to enable legend."""
if value not in [True,False]:
raise TypeError, "Value should be True or False"
self._legendEnabled= value
self.Redraw()
def GetEnableLegend(self):
"""True if Legend enabled."""
return self._legendEnabled
def Reset(self):
"""Unzoom the plot."""
if self.original_draw is not None:
self.Draw(self.original_draw[0],self.original_draw[1],self.original_draw[2])
def ScrollRight(self, units):
"""Move view right number of axis units."""
if self.last_draw is not None:
graphics, xAxis, yAxis= self.last_draw
xAxis= (xAxis[0]+units, xAxis[1]+units)
self.Draw(graphics,xAxis,yAxis)
def ScrollUp(self, units):
"""Move view up number of axis units."""
if self.last_draw is not None:
graphics, xAxis, yAxis= self.last_draw
yAxis= (yAxis[0]+units, yAxis[1]+units)
self.Draw(graphics,xAxis,yAxis)
def GetXY(self,event):
"""Takes a mouse event and returns the XY user axis values."""
screenPos= scipy.array( event.GetPosition())
x,y= (screenPos-self._pointShift)/self._pointScale
return x,y
def SetXSpec(self, type= 'auto'):
"""xSpec- defines x axis type. Can be 'none', 'min' or 'auto'
where:
'none' - shows no axis or tick mark values
'min' - shows min bounding box values
'auto' - rounds axis range to sensible values
"""
self._xSpec= type
def SetYSpec(self, type= 'auto'):
"""ySpec- defines x axis type. Can be 'none', 'min' or 'auto'
where:
'none' - shows no axis or tick mark values
'min' - shows min bounding box values
'auto' - rounds axis range to sensible values
"""
self._ySpec= type
def SetLegendItems(self,num= 10**5):
"""Truncate the legend so that only a few objects are returned"""
self._legendItems = num
def GetXSpec(self):
"""Returns current XSpec for axis"""
return self._xSpec
def GetYSpec(self):
"""Returns current YSpec for axis"""
return self._ySpec
def GetXMaxRange(self):
"""Returns (minX, maxX) x-axis range for displayed graph"""
graphics= self.last_draw[0]
p1, p2 = graphics.boundingBox() #min, max points of graphics
xAxis = self._axisInterval(self._xSpec, p1[0], p2[0]) #in user units
return xAxis
def GetYMaxRange(self):
"""Returns (minY, maxY) y-axis range for displayed graph"""
graphics= self.last_draw[0]
p1, p2 = graphics.boundingBox() #min, max points of graphics
yAxis = self._axisInterval(self._ySpec, p1[1], p2[1])
return yAxis
def GetXCurrentRange(self):
"""Returns (minX, maxX) x-axis for currently displayed portion of graph"""
return self.last_draw[1]
def GetYCurrentRange(self):
"""Returns (minY, maxY) y-axis for currently displayed portion of graph"""
return self.last_draw[2]
def Draw(self, graphics, xAxis = None, yAxis = None, dc = None):
"""Draw objects in graphics with specified x and y axis.
graphics- instance of PlotGraphics with list of PolyXXX objects
xAxis - tuple with (min, max) axis range to view
yAxis - same as xAxis
dc - drawing context - doesn't have to be specified.
If it's not, the offscreen buffer is used
"""
#check Axis is either tuple or none
if type(xAxis) not in [type(None),tuple]:
raise TypeError, "xAxis should be None or (minX,maxX)"
if type(yAxis) not in [type(None),tuple]:
raise TypeError, "yAxis should be None or (minY,maxY)"
#check case for axis = (a,b) where a==b caused by improper zooms
if xAxis != None:
if xAxis[0] == xAxis[1]:
return
if yAxis != None:
if yAxis[0] == yAxis[1]:
return
if dc == None:
# allows using floats for certain functions
dc = FloatDCWrapper(wx.wxBufferedDC(wx.wxClientDC(self), self._Buffer))
dc.Clear()
dc.BeginDrawing()
#dc.Clear()
#set font size for every thing but title and legend
dc.SetFont(self._getFont(self._fontSizeAxis))
#sizes axis to axis type, create lower left and upper right corners of plot
if xAxis == None or yAxis == None:
#One or both axis not specified in Draw
p1, p2 = graphics.boundingBox() #min, max points of graphics
if xAxis == None:
xAxis = self._axisInterval(self._xSpec, p1[0], p2[0]) #in user units
if yAxis == None:
yAxis = self._axisInterval(self._ySpec, p1[1], p2[1])
#Adjust bounding box for axis spec
p1[0],p1[1] = xAxis[0], yAxis[0] #lower left corner user scale (xmin,ymin)
p2[0],p2[1] = xAxis[1], yAxis[1] #upper right corner user scale (xmax,ymax)
else:
#Both axis specified in Draw
p1= scipy.array([xAxis[0], yAxis[0]]) #lower left corner user scale (xmin,ymin)
p2= scipy.array([xAxis[1], yAxis[1]]) #upper right corner user scale (xmax,ymax)
if self.last_draw == None:
self.x,self.y = xAxis,yAxis
else:
if abs(xAxis[0]-xAxis[1]) > abs(self.x[0]-self.x[1]):
self.x = xAxis
if abs(yAxis[0]-yAxis[1]) > abs(self.y[0]-self.y[1]):
self.y = yAxis
self.original_draw = (graphics, self.x, self.y)
self.last_draw = (graphics, xAxis, yAxis) #saves most recient values
#Get ticks and textExtents for axis if required
if self._xSpec is not 'none':
xticks = self._ticks(xAxis[0], xAxis[1])
xTextExtent = dc.GetTextExtent(xticks[-1][1])#w h of x axis text last number on axis
else:
xticks = None
xTextExtent= (0,0) #No text for ticks
if self._ySpec is not 'none':
yticks = self._ticks(yAxis[0], yAxis[1])
yTextExtentBottom= dc.GetTextExtent(yticks[0][1])
yTextExtentTop = dc.GetTextExtent(yticks[-1][1])
yTextExtent= (max(yTextExtentBottom[0],yTextExtentTop[0]),
max(yTextExtentBottom[1],yTextExtentTop[1]))
else:
yticks = None
yTextExtent= (0,0) #No text for ticks
#TextExtents for Title and Axis Labels
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -