Setting single Y label of limits Matplotlib or PyQtGraph? - python

How to add all limits value in left side single/single Y-label using matplotlib or pyqtgraph. I've managed a sample chart and attached here.
import wx
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
class TopPanel(wx.Panel):
def __init__(self,parent):
wx.Panel.__init__(self, parent = parent)
self.figure = Figure()
#wx.Button(self,wx.ID_ANY, label="Button 1")
self.SetBackgroundColour("red")
self.axes = self.figure.add_subplot(111)
self.canvas = FigureCanvas(self,-1,self.figure)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.canvas, 1, wx.EXPAND)
self.SetSizer(self.sizer)
self.axes.set_xlabel("Time")
self.axes.set_ylabel("A/D Counts")
def draw(self):
x = np.arange(0,5,0.01)
y = np.sin(np.pi*x)
self.axes.plot(x,y)
def changeAxes(self, min, max):
self.axes.set_ylim(float(min),float(max))
self.canvas.draw()
class BottomPanel(wx.Panel):
def __init__(self,parent, top):
wx.Panel.__init__(self, parent = parent)
#wx.Button(self,wx.ID_ANY, label="Button 2")
#self.SetBackgroundColour('Blue')
self.graph = top
self.togglebuttonStart = wx.ToggleButton(self,wx.ID_ANY,label="Start", pos=(10,10))
self.togglebuttonStart.Bind(wx.EVT_TOGGLEBUTTON, self.OnStartClick)
labelChannels = wx.StaticText(self, wx.ID_ANY, "Analog Inputs", pos=(200, 10))
self.cbl0 = wx.CheckBox(self,wx.ID_ANY, "A0", pos=(200, 30))
self.cbl1 = wx.CheckBox(self, wx.ID_ANY, "A1", pos=(200, 45))
self.cbl2 = wx.CheckBox(self, wx.ID_ANY, "A2", pos=(200, 60))
self.Bind(wx.EVT_CHECKBOX, self.OnChecked)
self.textboxSampleTime = wx.TextCtrl(self,wx.ID_ANY, "1000", pos=(200,115), size=(50,-1))
self.ButtonSend = wx.Button(self,wx.ID_ANY, "Send", pos=(255,115), size=(50,-1))
self.ButtonSend.Bind(wx.EVT_BUTTON, self.OnSend)
# A0 limit Values
labelMinY0 = wx.StaticText(self,wx.ID_ANY,"A0 Min Y", pos=(400,10))
self.textboxMinYAxis0 = wx.TextCtrl(self,wx.ID_ANY, "0", pos=(400,30))
labelMaxY0 = wx.StaticText(self, wx.ID_ANY, "A0 Max Y", pos=(400, 55))
self.textboxMaxYAxis0 = wx.TextCtrl(self, wx.ID_ANY, "1024", pos=(400, 75))
self.buttonRange0 = wx.Button(self, wx.ID_ANY, "Set Y0 Axis", pos=(400, 115))
self.buttonRange0.Bind(wx.EVT_BUTTON, self.SetButtonRange0)
# A1 limit Values
labelMinY1 = wx.StaticText(self, wx.ID_ANY, "A1 Min Y", pos=(530, 10))
self.textboxMinYAxis1 = wx.TextCtrl(self, wx.ID_ANY, "0", pos=(530, 30))
labelMaxY1 = wx.StaticText(self, wx.ID_ANY, "A1 Max Y", pos=(530, 55))
self.textboxMaxYAxis1 = wx.TextCtrl(self, wx.ID_ANY, "1024", pos=(530, 75))
self.buttonRange1 = wx.Button(self, wx.ID_ANY, "Set Y1 Axis", pos=(530, 115))
self.buttonRange1.Bind(wx.EVT_BUTTON, self.SetButtonRange1)
# A2 limit Values
labelMinY2 = wx.StaticText(self, wx.ID_ANY, "A2 Min Y", pos=(650, 10))
self.textboxMinYAxis2 = wx.TextCtrl(self, wx.ID_ANY, "0", pos=(650, 30))
labelMaxY2 = wx.StaticText(self, wx.ID_ANY, "A2 Max Y", pos=(650, 55))
self.textboxMaxYAxis2 = wx.TextCtrl(self, wx.ID_ANY, "1024", pos=(650, 75))
self.buttonRange2 = wx.Button(self, wx.ID_ANY, "Set Y2 Axis", pos=(650, 115))
self.buttonRange2.Bind(wx.EVT_BUTTON, self.SetButtonRange2)
def SetButtonRange0(self, event):
#print("Axis Button Clicked")
min = self.textboxMinYAxis0.GetValue()
max = self.textboxMaxYAxis0.GetValue()
print("(%s, %s)"% (min, max))
self.graph.changeAxes(min,max); # How to add it to Single Y-axis label?
def SetButtonRange1(self, event):
# print("Axis Button Clicked")
min = self.textboxMinYAxis1.GetValue()
max = self.textboxMaxYAxis1.GetValue()
print("(%s, %s)" % (min, max))
self.graph.changeAxes(min, max); # How to add it to Single Y-axis label?
def SetButtonRange2(self, event):
# print("Axis Button Clicked")
min = self.textboxMinYAxis2.GetValue()
max = self.textboxMaxYAxis2.GetValue()
print("(%s, %s)" % (min, max))
How to add it to Single Y-axis label?
self.graph.changeAxes(min, max);
def OnSend(self,event):
val = self.textboxSampleTime.GetValue()
print(val)
def OnChecked(self,event):
cb = event.GetEventObject()
print("%s is clicked" %(cb.GetLabel()))
def OnStartClick(self,event):
val = self.togglebuttonStart.GetValue()
if(val == True):
self.togglebuttonStart.SetLabel("Stop")
self.togglebuttonStart.SetBackgroundColour("red")
else:
self.togglebuttonStart.SetLabel("Start")
self.togglebuttonStart.SetBackgroundColour("green")
class Main(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent=None, title="App v0", size=(600,600))
splitter = wx.SplitterWindow(self)
top = TopPanel(splitter)
#bottom = BottomPanel(splitter)
bottom = BottomPanel(splitter,top)
splitter.SplitHorizontally(top, bottom)
splitter.SetMinimumPaneSize(300)
top.draw()
if __name__ == '__main__':
app = wx.App()
frame = Main()
frame.Show()
app.MainLoop()
The codes are done with WxPython and matplotlib. The top panel is for plotting line graph and bottom is for changing Y limits.
Image:Chart with multiple input limits in single Y axis
** Like this

Related

Weird black squares appear when switching tabs using wxpython

I'm using wxpython to create a GUI.
The idea is that whenever I select a row, something will happen on notebook1 and notebook 2, and different tabs will appear with different related information.
However, when I bind an event when selecting a row, weird beird black squares appear on the tab titles. What's wrong?
import wx
import threading
from time import sleep
class VAR():
def __init__(self):
self.result_row = ''
var = VAR()
class TabOne(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
t = wx.StaticText(self, -1, "This is the first tab", (20, 20))
class TabTwo(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
t = wx.StaticText(self, -1, "This is the second tab", (20, 20))
class GUI(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(1000, 1000), style=wx.DEFAULT_FRAME_STYLE &
~wx.MAXIMIZE_BOX ^ wx.RESIZE_BORDER, pos=(100, 0))
self.panel = wx.Panel(self)
self.hsizer = wx.BoxSizer(wx.VERTICAL)
first_panel = wx.Panel(self.panel, size=(1000, 420))
self.hsizer.Add(first_panel, 1)
self.second_panel = wx.Panel(self.panel, size=(1000, 600))
self.notebook1 = wx.Notebook(self.second_panel, size=(1000, 230))
self.notebook2 = wx.Notebook(self.second_panel, size=(1000, 400))
self.hsizer.Add(self.second_panel, 1)
self.second_panel_sizer = wx.BoxSizer(wx.VERTICAL)
self.second_panel_sizer.Add(self.notebook1, 1, wx.EXPAND)
self.second_panel_sizer.Add(self.notebook2, 2, wx.EXPAND)
self.second_panel.SetSizerAndFit(self.second_panel_sizer)
self.panel.SetSizerAndFit(self.hsizer)
var.result_row = wx.ListCtrl(
first_panel, -1, style=wx.LC_REPORT, size=(980, 245), pos=(0, 175))
var.result_row.InsertColumn(0, "No.")
var.result_row.InsertColumn(1, "2 ")
self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.SelectRow, var.result_row)
def SelectRow(self, event):
while (self.notebook1.GetPageCount()):
self.notebook1.DeletePage(0)
while (self.notebook2.GetPageCount()):
self.notebook2.DeletePage(0)
tab1 = TabOne(self.notebook1)
self.notebook1.AddPage(tab1, "Tab 1")
sizer = wx.BoxSizer()
sizer.Add(self.notebook1, 1, wx.EXPAND)
self.second_panel.SetSizer(sizer)
tab2 = TabTwo(self.notebook2)
self.notebook2.AddPage(tab2, "Tab 2")
sizer = wx.BoxSizer()
sizer.Add(self.notebook2, 1, wx.EXPAND)
self.second_panel.SetSizer(sizer)
def InfiniteProcess():
for i in range(100):
sleep(0.1)
var.result_row.Append(str(i))
finish = False
a = threading.Thread(target=InfiniteProcess)
a.setDaemon(1)
a.start()
app = wx.App()
frame = GUI(None, -1, "a")
frame.Show()
app.MainLoop()
sample

TextCtrl doesn't work properly with CheckBox

I wrote a code to receive some input data from user using both CheckBox and TextCtrl. The problem is when I marked the checkbox and textctrl appears, it accept to receive input data, but won't replace with the default one!
import wx
class mainClass(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Interface', size=(500, 250))
self.panel = wx.Panel(self)
self.checkReplaceJob = wx.CheckBox(self.panel, -1, "Replace data", (35, 60), (235, 20))
self.Bind(wx.EVT_CHECKBOX, self.replaceJob, self.checkReplaceJob)
self.RunBut = wx.Button(self.panel, -1, "Run", pos=(150, 150))
self.Bind(wx.EVT_BUTTON, self.RunClick, self.RunBut)
self.RunBut.SetDefault()
self.CloseBut = wx.Button(self.panel, -1, "Close", pos=(250, 150))
self.Bind(wx.EVT_BUTTON, self.CloseClick, self.CloseBut)
def CloseClick(self, event):
self.Close()
def replaceJob(self, event):
if(self.checkReplaceJob.IsChecked()):
self.repJobRetName()
self.btn = wx.Button(self.panel, wx.ID_ANY, "&Help", pos=(345, 82))
self.Bind(wx.EVT_BUTTON, self.HelpJobName, self.btn)
def repJobRetName(self):
self.label = wx.StaticText(self.panel, -1, label = "New name:", pos=(165,87))
self.entry = wx.TextCtrl(self.panel, -1, value = u"Task-1", pos=(230, 84))
repJobName = self.entry.GetValue()
return repJobName
def HelpJobName(self, event):
help = 'Write out new name.'
wx.MessageBox(help, "Help")
def RunClick(self, event):
if(self.checkReplaceJob.IsChecked()):
replaceName = self.repJobRetName()
wx.MessageBox('The new name is: ' + replaceName, "Info")
#############=======================
if __name__ == "__main__":
app = wx.App(False)
mainClass().Show()
app.MainLoop()
Let me make sure I understand correctly. You want the text control to have a default value when it is created, but you want that value to disappear when you actually select the control. Is that correct? If so, then you just need to add a binding to wx.EVT_SET_FOCUS and do a little work when the widget gets focus. Here's an example:
import wx
class mainClass(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Interface', size=(500, 250))
self.panel = wx.Panel(self)
self.checkReplaceJob = wx.CheckBox(self.panel, -1, "Replace data", (35, 60), (235, 20))
self.Bind(wx.EVT_CHECKBOX, self.replaceJob, self.checkReplaceJob)
self.RunBut = wx.Button(self.panel, -1, "Run", pos=(150, 150))
self.Bind(wx.EVT_BUTTON, self.RunClick, self.RunBut)
self.RunBut.SetDefault()
self.CloseBut = wx.Button(self.panel, -1, "Close", pos=(250, 150))
self.Bind(wx.EVT_BUTTON, self.CloseClick, self.CloseBut)
def CloseClick(self, event):
self.Close()
def replaceJob(self, event):
if(self.checkReplaceJob.IsChecked()):
self.repJobRetName()
self.btn = wx.Button(self.panel, wx.ID_ANY, "&Help", pos=(345, 82))
self.Bind(wx.EVT_BUTTON, self.HelpJobName, self.btn)
def repJobRetName(self):
self.label = wx.StaticText(self.panel, -1, label = "New name:", pos=(165,87))
self.entry = wx.TextCtrl(self.panel, -1, value = u"Task-1", pos=(230, 84))
self.entry.Bind(wx.EVT_SET_FOCUS, self.onFocus)
repJobName = self.entry.GetValue()
return repJobName
def onFocus(self, event):
current_value = self.entry.GetValue()
if current_value == "Task-1":
self.entry.SetValue("")
def HelpJobName(self, event):
help = 'Write out new name.'
wx.MessageBox(help, "Help")
def RunClick(self, event):
if(self.checkReplaceJob.IsChecked()):
replaceName = self.repJobRetName()
wx.MessageBox('The new name is: ' + replaceName, "Info")
#############=======================
if __name__ == "__main__":
app = wx.App(False)
mainClass().Show()
app.MainLoop()

wxpython frame update with a button click

In progress of making an wxpython assignment for school, I stumbled on something I can't seem to figure out by myself.
The main idea of the assignment is to make a self-generating quiz. Now I made a frame were the questions should be in the future.
I need this frame to update itself with the button for the next question (middle one), so the next question is showing when clicking the button.
Before actually doing that I tried testing it with a random number generator. But the update button doesn't seem to update to a new frame with a new number (looking the same, only the number changing). I know I'm missing something, but I don't know where to start.
Here is my code:
import wx
import random
class welkom(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, "Aminozuurtoets V.1.0", size=(900,600))
self.mainFrame = mainFrame
top_panel = wx.Panel(self)
w_tekst = wx.StaticText(top_panel, -1, "Welkom bij de aminozuurtoets",(325,50), (100, -1), wx.ALIGN_CENTER)
w_font = wx.Font(20, wx.DECORATIVE, wx.ITALIC, wx.NORMAL)
w_tekst.SetFont(w_font)
st_nr = wx.StaticText(top_panel, -1, 'Studentnummer' ,(100,150))
inp_st_nr = wx.TextCtrl(top_panel, -1, '', (300,150), size=(140,-1))
st_vr= wx.StaticText(top_panel, -1, 'Student voornaam' ,(100,200))
inp_st_vr = wx.TextCtrl(top_panel, -1, '', (300,200), size=(140,-1))
st_ach = wx.StaticText(top_panel, -1, 'Student achternaam' ,(100,250))
inp_st_ach = wx.TextCtrl(top_panel, -1, '', (300,250), size=(140,-1))
aan_vr = wx.StaticText(top_panel, -1, 'Aantal vragen' ,(100,300))
inp_aan_vr = wx.TextCtrl(top_panel, -1, '20', (300,300), size=(140,-1))
close_button = wx.Button(top_panel, label = "Stoppen", pos=(600, 400), size=(150, 200))
self.Bind(wx.EVT_BUTTON, self.closebutton, close_button)
go_button = wx.Button(top_panel, label = "Doorgaan", pos=(100, 400), size=(150, 200))
self.Bind(wx.EVT_BUTTON, self.buttonClick, go_button)
def closebutton(self, event):
self.Close(True)
def buttonClick(self, event):
self.Hide()
self.mainFrame(None, id = -1).Show()
class mainFrame(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, "Aminozuurtoets V.1.0", size=(900,600))
top_panel = wx.Panel(self)
self.vraag = 1
m_tekst = wx.StaticText(top_panel, -1, "Vraag " + str(self.vraag),(400,50), (100, -1), wx.ALIGN_CENTER)
m_font = wx.Font(20, wx.DECORATIVE, wx.ITALIC, wx.NORMAL)
m_tekst.SetFont(m_font)
cijfer = random.randint(1,100)
test2 = wx.StaticText(top_panel, -1, str(cijfer), (325,300))
res_but = wx.Button(top_panel, label = "Resultaten", pos=(650, 400), size=(150, 200))
ga_naar = wx.Button(top_panel, label = "Ga naar vraag", pos=(100, 400), size=(150, 200))
ga_button = wx.Button(top_panel, label = "Volgende vraag", pos=(380, 400), size=(150, 200))
self.Bind(wx.EVT_BUTTON, self.buttonClick1, ga_button)
def buttonClick1(self, event):
self.Update()
def closebutton(self, event):
self.Close(True)
app = wx.App()
frame = welkom(None, id = -1).Show()
app.MainLoop()
Just calling Update doesn't change nothing. I changed mainFrame class. (See comments that starts with ###)
class mainFrame(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, "Aminozuurtoets V.1.0", size=(900,600))
top_panel = wx.Panel(self)
self.vraag = 1
m_tekst = wx.StaticText(top_panel, -1, "Vraag " + str(self.vraag),(400,50), (100, -1), wx.ALIGN_CENTER)
m_font = wx.Font(20, wx.DECORATIVE, wx.ITALIC, wx.NORMAL)
m_tekst.SetFont(m_font)
cijfer = random.randint(1,100)
### Make an attribute to access from buttonClick1 method.
self.test2 = wx.StaticText(top_panel, -1, str(cijfer), (325,300))
res_but = wx.Button(top_panel, label = "Resultaten", pos=(650, 400), size=(150, 200))
ga_naar = wx.Button(top_panel, label = "Ga naar vraag", pos=(100, 400), size=(150, 200))
ga_button = wx.Button(top_panel, label = "Volgende vraag", pos=(380, 400), size=(150, 200))
self.Bind(wx.EVT_BUTTON, self.buttonClick1, ga_button)
def buttonClick1(self, event):
### Change label of static text.
self.test2.Label = str(random.randint(1,100))
def closebutton(self, event):
self.Close(True)

Why is my second label not updating?

For some reason, I can't update the second label. I tested it by asking for input and print out strings and it worked so I apparently did not write the label update function correctly. Any ideas?
import wx
import time
class LeftPanel(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
self.text = parent.GetParent().rightPanel.text
self.text_2 = parent.GetParent().rightPanel.text_2
button1 = wx.Button(self, -1, 'Count', (10, 10))
button2 = wx.Button(self, -1, 'Countdown', (10, 60))
button3 = wx.Button(self, -1, 'Action', (10, 110))
self.Bind(wx.EVT_BUTTON, self.OnPlus, id=button1.GetId())
self.Bind(wx.EVT_BUTTON, self.OnMinus, id=button2.GetId())
self.Bind(wx.EVT_BUTTON, self.button_Pressed, id=button3.GetId())
self.timed_Out = 1
def OnPlus(self, event):
value = 1
for t in range(50):
value = value + 1
time.sleep(1)
wx.Yield()
self.text.SetLabel(str(value))
def OnMinus(self, event):
value = 60
for t in range(value):
value = value - 1
time.sleep(1)
wx.Yield()
self.text.SetLabel(str(value/60) + ':' + str(value%60))
self.timed_Out = 0
self.text_2.SetLabel(str('End o\'line.'))
def button_Pressed(self, event):
if self.timed_Out == 1:
if self.text_2 == 'First':
self.text_2.SetLabel('Second')
elif self.text_2 == 'Second':
self.text_2.SetLabel('First')
class RightPanel(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
self.text = wx.StaticText(self, -1, '0', (10,60))
self.text_2 = wx.StaticText(self,-1,'First',(10, 120))
class Communicate(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600, 200))
panel = wx.Panel(self, -1)
self.rightPanel = RightPanel(panel, -1)
leftPanel = LeftPanel(panel, -1)
hbox = wx.BoxSizer()
hbox.Add(leftPanel, 1, wx.EXPAND | wx.ALL, 4)
hbox.Add(self.rightPanel, 1, wx.EXPAND | wx.ALL, 5)
panel.SetSizer(hbox)
self.Centre()
self.Show(True)
app = wx.App()
Communicate(None, -1, 'widgets communicate')
app.MainLoop()
In button_Pressed, you're testing self.text_2 for equality with "First" or "Second", but text_2 is a StaticText object, not a string, so the test doesn't work. Try this:
if self.text_2.GetLabelText() == 'First':

How to update a plot with python and Matplotlib

I have been bashing my head against the wall trying to update a graph using matplotlib with python and wxpython. I want to press a button and add data to a graph nested in a wx.notebook. Below is the code.
Thanks for the help
import wx
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
class Plot(wx.Panel):
def __init__(self, parent, id = -1, dpi = None, **kwargs):
wx.Panel.__init__(self, parent, id=id, **kwargs)
self.figure = mpl.figure.Figure(dpi=dpi, figsize=(2,2))
self.canvas = Canvas(self, -1, self.figure)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.canvas,1,wx.EXPAND)
self.SetSizer(sizer)
class JBC(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600,600))
self.SetBackgroundColour(wx.Colour(236, 233, 216))
self.nbG = wx.Notebook(self, -1, style=0, size=(400,400), pos=(0,0))
self.gSheet1 = self.add("Test").gca()
calcButton = wx.Button(self, wx.NewId(), "Update", pos=(0, self.nbG.Position.y+400))
#self.gSheet1.hold(False)
#self.gSheet1.set_xlim(0,20)
#self.gSheet1.set_ylim(0,20)
#for i in range (2):
# self.gSheet1.plot([0,10],[1*i,1+i])
#axes2 = plotter.add('figure 2').gca()
#axes2.plot([1,2,3,4,5],[2,1,4,2,3])
self.Bind(wx.EVT_BUTTON, self.OnCalculate, calcButton)
self.Show(True)
def OnCalculate(self, event):
self.gSheet1.set_xlim(0,20)
self.gSheet1.set_ylim(0,20)
self.gSheet1.plot([1,2,3,4,5],[2,1,4,2,3])
self.Update()
def add(self,name="plot"):
page = Plot(self.nbG)
self.nbG.AddPage(page,name)
return page.figure
def Update(self):
self.gSheet1.clear()
plt.draw()
print "Tried to redraw"
app = wx.App()
JBC(None, -1, "Test Title")
app.MainLoop()
Using this example as a guide, perhaps try this:
import wx
import matplotlib as mpl
mpl.use('WXAgg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas
class Plot(wx.Panel):
def __init__(self, parent, id = -1, dpi = None, **kwargs):
wx.Panel.__init__(self, parent, id=id, **kwargs)
self.figure = mpl.figure.Figure(dpi=dpi, figsize=(2,2))
self.canvas = Canvas(self, -1, self.figure)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.canvas,1,wx.EXPAND)
self.SetSizer(sizer)
class JBC(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600,600))
self.SetBackgroundColour(wx.Colour(236, 233, 216))
self.nbG = wx.Notebook(self, -1, style=0, size=(400,400), pos=(0,0))
self.gSheet1 = self.add("Test").gca()
calcButton = wx.Button(self, wx.NewId(), "Update", pos=(0, self.nbG.Position.y+400))
#self.gSheet1.hold(False)
#self.gSheet1.set_xlim(0,20)
#self.gSheet1.set_ylim(0,20)
#for i in range (2):
# self.gSheet1.plot([0,10],[1*i,1+i])
#axes2 = plotter.add('figure 2').gca()
#axes2.plot([1,2,3,4,5],[2,1,4,2,3])
self.Bind(wx.EVT_BUTTON, self.OnCalculate, calcButton)
# self.Show(True)
def OnCalculate(self, event):
self.gSheet1.set_xlim(0,20)
self.gSheet1.set_ylim(0,20)
self.gSheet1.plot([1,2,3,4,5],[2,1,4,2,3])
self.Update()
def add(self,name="plot"):
page = Plot(self.nbG)
self.nbG.AddPage(page,name)
return page.figure
def Update(self):
self.gSheet1.clear()
plt.draw()
print "Tried to redraw"
if __name__ == '__main__':
app = wx.App()
frame=JBC(None, -1, "Test Title")
frame.Show()
app.MainLoop()
It is also possible to use matplotlib to draw an animated figure:
"""
Based on Tkinter bouncing ball code:
http://stackoverflow.com/q/13660042/190597 (arynaq) and
http://eli.thegreenplace.net/2008/08/01/matplotlib-with-wxpython-guis/
"""
import wx
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.figure as mplfig
import scipy.spatial.distance as dist
import matplotlib.backends.backend_wxagg as mwx
class Frame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, size = (800, 600))
self.panel = wx.Panel(self)
self.fig = mplfig.Figure(figsize = (5, 4), dpi = 100)
self.ax = self.fig.add_subplot(111)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.canvas = mwx.FigureCanvasWxAgg(self.panel, wx.ID_ANY, self.fig)
self.toolbar = mwx.NavigationToolbar2WxAgg(self.canvas)
self.button = wx.Button(self.panel, wx.ID_ANY, "Quit")
self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
self.vbox.Add(self.toolbar, 0, wx.EXPAND)
self.vbox.Add(
self.button, 0, border = 3,
flag = wx.ALIGN_LEFT | wx.ALL | wx.ALIGN_CENTER_VERTICAL)
self.panel.SetSizer(self.vbox)
self.vbox.Fit(self)
self.toolbar.update()
self.update = self.animate().next
self.timer = wx.Timer(self)
self.timer.Start(1)
self.Bind(wx.EVT_BUTTON, self.OnCloseWindow, self.button)
self.Bind(wx.EVT_TIMER, lambda event: self.update())
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
def OnCloseWindow(self, evt):
self.timer.Stop()
del self.timer
self.Destroy()
def animate(self):
N = 100 #Number of particles
R = 10000 #Box width
pR = 5 #Particle radius
r = np.random.randint(0, R, (N, 2)) #Position vector
v = np.random.randint(-R/100, R/100, (N, 2)) #velocity vector
a = np.array([0, -10]) #Forces
v_limit = R/2 #Speedlimit
line, = self.ax.plot([], 'o')
line2, = self.ax.plot([], 'o') #Track a particle
self.ax.set_xlim(0, R+pR)
self.ax.set_ylim(0, R+pR)
while True:
v = v+a #Advance
r = r+v
#Collision tests
r_hit_x0 = np.where(r[:, 0]<0) #Hit floor?
r_hit_x1 = np.where(r[:, 0]>R) #Hit roof?
r_hit_LR = np.where(r[:, 1]<0) #Left wall?
r_hit_RR = np.where(r[:, 1]>R) #Right wall?
#Stop at walls
r[r_hit_x0, 0] = 0
r[r_hit_x1, 0] = R
r[r_hit_LR, 1] = 0
r[r_hit_RR, 1] = R
#Reverse velocities
v[r_hit_x0, 0] = -0.9*v[r_hit_x0, 0]
v[r_hit_x1, 0] = -v[r_hit_x1, 0]
v[r_hit_LR, 1] = -0.95*v[r_hit_LR, 1]
v[r_hit_RR, 1] = -0.99*v[r_hit_RR, 1]
#Collisions
D = dist.squareform(dist.pdist(r))
ind1, ind2 = np.where(D < pR)
unique = (ind1 < ind2)
ind1 = ind1[unique]
ind2 = ind2[unique]
for i1, i2 in zip(ind1, ind2):
eps = np.random.rand()
vtot = v[i1, :]+v[i2, :]
v[i1, :] = -(1-eps)*vtot
v[i2, :] = -eps*vtot
line.set_ydata(r[:, 1])
line.set_xdata(r[:, 0])
line2.set_ydata(r[:N/5, 1])
line2.set_xdata(r[:N/5, 0])
self.canvas.draw()
yield True
def main():
app = wx.App(False)
frame = Frame()
frame.Show(True)
app.MainLoop()
if __name__ == '__main__':
main()

Categories

Resources