Python : QWidget: Must construct a QApplication before a QPaintDevice - python

I am trying to plot graphs using matplotlib when clicked on a button called "generate graph" in a QT window. At first, I found a problem : I cannot close plots or control it when the QT window is opened. But I found this solution :
Cannot move Matplotlib plot window and exit it using red X button
and I test it on an empty plot and it works. However, when I put my code I get this error :
QWidget: Must construct a QApplication before a QPaintDevice
In my qt window I put :
Process = subprocess.Popen(['python', 'mygraph.py'], shell=True).communicate()
in my script mygraph.py :
def main():
print("Beginning plot for section 2.1 ...")
#Get the selected iteration and sector
iter = InterfaceVariationTRANUS("config").DropDownListDisplayIter2_1.currentIndex()
sector = InterfaceVariationTRANUS("config").DropDownListDisplaySector2_1.currentIndex()
#Access the corresponding IMPLOC file and extract the data for the selected sector
nameDirectory = InterfaceVariationTRANUS("config").nameDirectory2_1 + str(iter)
pathToDirectory = os.path.join(InterfaceVariationTRANUS("config").pathOutputDirectoryInstance, nameDirectory)
filepath = os.path.join(pathToDirectory, "IMPLOC_J.MTX")
matrix = pd.read_csv(filepath)
matrix.columns = ["Scen", "Sector", "Zone", "TotProd", "TotDem", "ProdCost", "Price", "MinRes", "MaxRes", "Adjust"]
#Removal of the noise (production equal to zero => adjust equal to zero)
#matrix.Adjust[matrix.TotProd == 0] = 0
row_index = matrix.TotProd == 0
matrix.loc[row_index,'Adjust'] = 0
#matrix.Adjust[matrix.Price == 0] = 0
row_index = matrix.Price == 0
matrix.loc[row_index,'Adjust'] =0
#matrix.Price[matrix.Price == 0] = None
row_index = matrix.Price == 0
matrix.loc[row_index,'Price'] = None
matrix2 = matrix[["Sector","Zone", "Price", "Adjust"]]
#Isolation of the data for the sector selected
nameSector = str(InterfaceVariationTRANUS("config").stockParam.list_sectors[sector])+" "+(InterfaceVariationTRANUS().stockParam.list_names_sectors[sector])
matrix3 = matrix2[matrix2["Sector"].str.contains(nameSector) == True]
matrix4 = matrix3[matrix3["Zone"].str.contains("ext_") == False]
#This boolean is used to allow for multiple graphes to be shown on the same panel.
firstPlot = False
#Plot graph and display it
if(InterfaceVariationTRANUS("config").DropDownListDisplaySector2_1.currentIndex() != InterfaceVariationTRANUS("config").currentSectorPlot2_1):
InterfaceVariationTRANUS("config").numFiguresPlot2_1 = InterfaceVariationTRANUS("config").numFiguresPlot2_1 + 1
InterfaceVariationTRANUS("config").currentSectorPlot2_1 = InterfaceVariationTRANUS("config").DropDownListDisplaySector2_1.currentIndex()
firstPlot = True
fig = plt.figure(self.numFiguresPlot2_1)
fig.canvas.set_window_title(InterfaceVariationTRANUS("config").DropDownListDisplaySector2_1.currentText())
x = np.arange(0, InterfaceVariationTRANUS("config").stockParam.nTotZones, 1)
y = pd.to_numeric(matrix4["Price"])
print("Moyenne = ")
print(y.mean(0))
z = pd.to_numeric(matrix4["Adjust"]*y)/100 + y
# plot data
if(firstPlot):
price = plt.plot(x, y, label = ("Price"))
shadowPrice = plt.plot(x, z, label = ("Price + adjust for iteration "+InterfaceVariationTRANUS("config").DropDownListDisplayIter2_1.currentText()))
plt.legend()
plt.show(block=False) #method 3
plt.draw()
if name == 'main':
main()
Where InterfaceVariationTRANUS is the class of my QT window.

Finally, I found a solution that works correctly for my problem :
import matplotlib.pyplot as plt
plt.switch_backend('Qt4Agg')
...
plt.legend()
plt.draw()
plt.show(block=False)

Related

Why are the indicators on my chart delayed by at least 1 day, making them not flush on the blue line? Is it because the time frame is too wide?

Why are the up triangles, when the program is supposed to buy, not on the line when it crosses under, or in the other scenario, the down triangle, when the program is supposed to sell, not on the line when it crosses on top? The blue line is the price and the red line is the EMA, tracking the price.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import requests
plt.style.use("fivethirtyeight")
df = pd.read_csv("TSLA.csv")
df = df.set_index(pd.DatetimeIndex(df["Date"].values))
ShortEMA = df.Close.ewm(span=5, adjust = False).mean()
MiddleEMA = df.Close.ewm(span = 21, adjust = False).mean()
LongEMA = df.Close.ewm(span = 53, adjust = False).mean()
df['Short'] = ShortEMA
df['Middle'] = MiddleEMA
df['Long'] = LongEMA
def MyStrat(data):
bought_list = []
sold_list = []
In = False
Out = True
for i in range(0, len(data)):
if data["Close"][i] > data["Short"][i] and In == False and Out == True:
bought_list.append(data["Close"][i])
sold_list.append(np.nan)
In = True
Out = False
elif data["Close"][i] < data["Short"][i] and In == True and Out == False:
sold_list.append(data["Close"][i])
bought_list.append(np.nan)
In = False
Out = True
else:
bought_list.append(np.nan)
sold_list.append(np.nan)
return(bought_list,sold_list)
df["Bought"] = MyStrat(df)[0]
df["Sold"] = MyStrat(df)[1]
print(df)
plt.figure(figsize=(16, 5))
plt.title('Buy and Sell', fontsize = 18)
plt.plot(df['Close'], label = 'Close Price', color = 'blue', alpha = 0.35)
plt.plot(ShortEMA, label = 'Short', color = 'red', alpha = 0.35)
plt.scatter(df.index, df["Bought"], color = "purple", marker = "^", alpha = 1)
plt.scatter(df.index, df["Sold"], color = "blue", marker = "v", alpha = 1)
plt.xlabel("Date", fontsize = 18)
plt.ylabel("Close", fontsize = 18)
plt.show()
You can use this data for reference:
Date,Open,High,Low,Close,Adj Close,Volume
2022-01-06,1077.000000,1088.000000,1020.500000,1064.699951,1064.699951,30112200
2022-01-07,1080.369995,1080.930054,1010.000000,1026.959961,1026.959961,28054900
2022-01-10,1000.000000,1059.099976,980.000000,1058.119995,1058.119995,30605000
2022-01-11,1053.670044,1075.849976,1038.819946,1064.400024,1064.400024,22021100
2022-01-12,1078.849976,1114.839966,1072.589966,1106.219971,1106.219971,27913000
2022-01-13,1109.069946,1115.599976,1026.540039,1031.560059,1031.560059,32403300
2022-01-14,1019.880005,1052.000000,1013.380005,1049.609985,1049.609985,24308100
2022-01-18,1026.609985,1070.790039,1016.059998,1030.510010,1030.510010,22247800
2022-01-19,1041.709961,1054.670044,995.000000,995.650024,995.650024,25147500
2022-01-20,1009.729980,1041.660034,994.000000,996.270020,996.270020,23496200
2022-01-21,996.340027,1004.549988,940.500000,943.900024,943.900024,34472000
2022-01-24,904.760010,933.510010,851.469971,930.000000,930.000000,50521900
2022-01-25,914.200012,951.260010,903.210022,918.400024,918.400024,28865300
2022-01-26,952.429993,987.690002,906.000000,937.409973,937.409973,34955800
2022-01-27,933.359985,935.390015,829.000000,829.099976,829.099976,49036500
2022-01-28,831.559998,857.500000,792.010010,846.349976,846.349976,44929700
2022-01-31,872.710022,937.989990,862.049988,936.719971,936.719971,34812000
2022-02-01,935.210022,943.700012,905.000000,931.250000,931.250000,24379400
2022-02-02,928.179993,931.500000,889.409973,905.659973,905.659973,22264300
2022-02-03,882.000000,937.000000,880.520020,891.140015,891.140015,26285200
2022-02-04,897.219971,936.500000,881.169983,923.320007,923.320007,24541800
2022-02-07,923.789978,947.770020,902.710022,907.340027,907.340027,20331500
2022-02-08,905.530029,926.289978,894.799988,922.000000,922.000000,16909700
2022-02-09,935.000000,946.270020,920.000000,932.000000,932.000000,17419800
2022-02-10,908.369995,943.809998,896.700012,904.549988,904.549988,22042300
2022-02-11,909.630005,915.960022,850.700012,860.000000,860.000000,26548600
2022-02-14,861.570007,898.880005,853.150024,875.760010,875.760010,22585500
2022-02-15,900.000000,923.000000,893.380005,922.429993,922.429993,19095400
2022-02-16,914.049988,926.429993,901.210022,923.390015,923.390015,17098100
2022-02-17,913.260010,918.500000,874.099976,876.349976,876.349976,18392800
2022-02-18,886.000000,886.869995,837.609985,856.979980,856.979980,22833900
2022-02-22,834.130005,856.729980,801.099976,821.530029,821.530029,27762700
2022-02-23,830.429993,835.299988,760.559998,764.039978,764.039978,31752300
2022-02-24,700.390015,802.479980,700.000000,800.770020,800.770020,45107400
2022-02-25,809.229980,819.500000,782.400024,809.869995,809.869995,25355900
2022-02-28,815.010010,876.859985,814.710022,870.429993,870.429993,33002300
2022-03-01,869.679993,889.880005,853.780029,864.369995,864.369995,24922300
2022-03-02,872.130005,886.479980,844.270020,879.890015,879.890015,24881100
2022-03-03,878.770020,886.440002,832.599976,839.289978,839.289978,20541200
2022-03-04,849.099976,855.650024,825.159973,838.289978,838.289978,22333200
2022-03-07,856.299988,866.140015,804.570007,804.580017,804.580017,24164700
2022-03-08,795.530029,849.989990,782.169983,824.400024,824.400024,26799700
2022-03-09,839.479980,860.559998,832.010010,858.969971,858.969971,19728000
2022-03-10,851.450012,854.450012,810.359985,838.299988,838.299988,19549500
2022-03-11,840.200012,843.799988,793.770020,795.349976,795.349976,22272800
2022-03-14,780.609985,800.700012,756.039978,766.369995,766.369995,23717400
2022-03-15,775.270020,805.570007,756.570007,801.890015,801.890015,22280400
2022-03-16,809.000000,842.000000,802.260010,840.229980,840.229980,28009600
2022-03-17,830.989990,875.000000,825.719971,871.599976,871.599976,22194300
2022-03-18,874.489990,907.849976,867.390015,905.390015,905.390015,33408500
2022-03-21,914.979980,942.849976,907.090027,921.159973,921.159973,27327200
2022-03-22,930.000000,997.859985,921.750000,993.979980,993.979980,35289500
2022-03-23,979.940002,1040.699951,976.400024,999.109985,999.109985,40225400
2022-03-24,1009.729980,1024.489990,988.799988,1013.919983,1013.919983,22973600
2022-03-25,1008.000000,1021.799988,997.320007,1010.640015,1010.640015,20642900
2022-03-28,1065.099976,1097.880005,1053.599976,1091.839966,1091.839966,34168700
2022-03-29,1107.989990,1114.770020,1073.109985,1099.569946,1099.569946,24538300
2022-03-30,1091.170044,1113.949951,1084.000000,1093.989990,1093.989990,19955000
2022-03-31,1094.569946,1103.140015,1076.640015,1077.599976,1077.599976,16265600
2022-03-31,1094.569946,1103.139893,1076.640991,1077.599976,1077.599976,16330919
The problem with this is that the point of intersection occurs between days, not on a specific day. As the data is not continuous, but rather just one point per business day, it is not possible to put the arrow on the intersection itself. I have enlarged a portion of the graph here so you can see what I mean. The change occurs between the 9th and 10th. The data is only on the 9th or the 10th, so the arrow is plotted, and the buy occurs, on the 10th.
The buy/sell is on the next possible day, causing the mis-alignment of the arrows.

Matplotlib backend notebook customizations

I'm using the matplotlib backend 'notebook', because I am making some interactive figures, and this works well with the notebook backend (in particular, I serve them via Jupyter Notebooks). I use ipywidgets to design the GUI and interactivity.
However, using this backend, there are all sorts of buttons that can interfere with my interactive figure. Especially, resizing, zooming, panning, or the power button, will lead to much confusion for my students...
I want to disable them. See this illustration on what I want to disable.
Can anyone point me to the relevant API pages or does anyone know how to disable/remove these buttons? I tried some other backends, but these typically will not work so well for interactive figures in Jupyter notebooks, so I want to stick to the notebook backend if possible.
This is the contents of svm_helper:
from matplotlib import pyplot as plt
from matplotlib.backend_bases import MouseButton as mb
import ipywidgets as widgets
import sklearn.linear_model
import sklearn.metrics
import sklearn.svm
import numpy as np
def plot_decision_boundary_margin(X, y, model):
Xmin = np.min(X[:,:],axis=0)
Xmax = np.max(X[:,:],axis=0)
Xmin = np.array([-3, -3])
Xmax = np.array([3, 3])
x0, x1 = np.meshgrid(
np.linspace(Xmin[0], Xmax[0], 500).reshape(-1, 1),
np.linspace(Xmin[1], Xmax[1], 200).reshape(-1, 1),
)
X_new = np.c_[x0.ravel(), x1.ravel()]
y_new = model.decision_function(X_new)
#plot_dataset(X,y)
zz = y_new.reshape(x0.shape)
C1 = plt.contour(x0, x1, zz, levels=np.array([0]),colors='k')
C2 = plt.contour(x0, x1, zz, levels=np.array([-1,1]),colors='k',linestyles='dashed')
return (C1, C2)
class LineBuilder2:
def __init__(self, lineR, lineB, widgetcolor, widgetC, my_out, need_seperable):
self.lineR = lineR
self.xsR = list(lineR.get_xdata())
self.ysR = list(lineR.get_ydata())
self.lineB = lineB
self.xsB = list(lineB.get_xdata())
self.ysB = list(lineB.get_ydata())
self.mywidgetcolor = widgetcolor
self.cid = lineR.figure.canvas.mpl_connect('button_press_event', self)
self.cid = lineR.figure.canvas.mpl_connect('motion_notify_event', self)
self.widgetC = widgetC
self.my_out = my_out
self.dragging_timer = 0
self.trained = False
self.model = None
self.C1 = None
self.C2 = None
self.need_seperable = need_seperable
def remove_decision_boundary(self):
if (self.C1 == None) or (self.C2 == None):
return
for coll in self.C1.collections:
plt.gca().collections.remove(coll)
for coll in self.C2.collections:
plt.gca().collections.remove(coll)
def __call__(self, event):
#print('click', event)
currently_dragging = False
if event.name == 'motion_notify_event':
currently_dragging = True
self.dragging_timer = self.dragging_timer+1
if self.dragging_timer > 5:
self.dragging_timer = 0
if not (event.button == mb.LEFT or event.button == mb.MIDDLE or event.button == mb.RIGHT):
return
if event.inaxes != self.lineB.axes:
return
#print(widgetcolor.value)
if self.mywidgetcolor.value == 'green':
self.xsR.append(event.xdata)
self.ysR.append(event.ydata)
if (not currently_dragging) or (currently_dragging and self.dragging_timer == 0):
self.lineR.set_data(self.xsR, self.ysR)
#self.lineR.figure.canvas.draw()
if self.mywidgetcolor.value == 'blue':
self.xsB.append(event.xdata)
self.ysB.append(event.ydata)
if (not currently_dragging) or (currently_dragging and self.dragging_timer == 0):
self.lineB.set_data(self.xsB, self.ysB)
#self.lineB.figure.canvas.draw()
#if self.dragging_timer == 0:
# self.lineR.figure.canvas.draw()
def clear(self, button):
if self.trained == False:
with self.my_out:
print('can only reset if trained')
return
with self.my_out:
print('resetted the widget')
self.trained = False
self.remove_decision_boundary()
self.C1 = None
self.C2 = None
self.model = None
self.xsR = []
self.ysR = []
self.xsB = []
self.ysB = []
self.lineR.set_data(self.xsR, self.ysR)
self.lineB.set_data(self.xsB, self.ysB)
self.lineB.figure.canvas.draw()
self.lineR.figure.canvas.draw()
def export(self):
dataR = np.array([self.xsR,self.ysR]).transpose()
dataB = np.array([self.xsB,self.ysB]).transpose()
yR = np.ones((dataR.shape[0], 1))
yB = -np.ones((dataB.shape[0], 1))
X = np.concatenate((dataR,dataB))
y = np.concatenate((yR,yB))
y = np.reshape(y,y.shape[0])
return (X,y)
def train(self, button):
self.my_out.clear_output()
if len(self.xsR) < 1 or len(self.xsB) < 1:
with self.my_out:
print('need at least one object in both classes to train')
return
(X,y) = self.export()
if self.need_seperable:
C = float('inf')
else:
C = self.widgetC.value
model = sklearn.svm.LinearSVC(loss='hinge',C=C)
model.fit(X,y)
if self.need_seperable:
acc = model.score(X,y)
if acc < 0.99999:
with self.my_out:
print('this dataset is not seperable')
return
self.remove_decision_boundary()
train_error = model.score(X,y)
(C1, C2) = plot_decision_boundary_margin(X,y,model)
self.C1 = C1
self.C2 = C2
self.model = model
self.trained = True
with self.my_out:
if self.need_seperable:
print('trained hard margin SVM')
else:
print('trained soft margin SVM with C %f' % C)
def init(need_seperable = True):
# Turn off interactivity, for now
plt.ioff()
fig = plt.figure(figsize = (4,4))
ax = fig.add_subplot(111)
# Make some nice axes
ax.set_xlim(-3, 3)
ax.set_ylim(-3, 3)
ax.set_title('click to add points')
ax.set_xlabel('Feature 1')
ax.set_ylabel('Feature 2')
# Remove some stuff from the backend
#fig.canvas.toolbar_visible = False # Hide toolbar
#fig.canvas.header_visible = False # Hide the Figure name at the top of the figure
#fig.canvas.footer_visible = False
#fig.canvas.resizable = False
# These items will contain the objects
lineR, = ax.plot([], [], linestyle="none", marker="s", color="g", markersize=10)
lineB, = ax.plot([], [], linestyle="none", marker="^", color="b", markersize=10)
# Make the GUI
w_clear = widgets.Button(
description='Clear all',
disabled=False,
button_style='danger', # 'success', 'info', 'warning', 'danger' or ''
tooltip='Remove all data and start from scratch',
icon='check' # (FontAwesome names without the `fa-` prefix)
)
w_color = widgets.ToggleButtons(
options=['green', 'blue'],
description='Class:',
disabled=False,
button_style='', # 'success', 'info', 'warning', 'danger' or ''
tooltips=['Description of slow', 'Description of regular'],
# icons=['check'] * 3
)
if not need_seperable:
w_C = widgets.FloatLogSlider(
value=1,
base=10,
min=-10, # max exponent of base
max=10, # min exponent of base
step=0.2, # exponent step
#description='Log Slider',
description='C:',
continuous_update=False,
orientation='horizontal',
readout=True,
#readout_format='.2f',
)
else:
w_C = None
w_train = widgets.Button(
description='Train SVM',
disabled=False,
button_style='warning', # 'success', 'info', 'warning', 'danger' or ''
tooltip='...',
icon='check' # (FontAwesome names without the `fa-` prefix)
)
out = widgets.Output(layout={'border': '1px solid black'})
out.layout.height = '40px'
out.layout.width = '600px'
if need_seperable:
b1 = widgets.HBox([w_color,w_train])
bar = widgets.VBox([b1, out])
else:
b1 = widgets.HBox([w_color,w_C,w_train])
#b2 = widgets.HBox([w_train,w_C])
bar = widgets.VBox([b1, out])
linebuilder = LineBuilder2(lineR, lineB, w_color, w_C, out, need_seperable)
w_clear.on_click(linebuilder.clear)
w_train.on_click(linebuilder.train)
# Turn interactivity back on
plt.ion()
out = fig
ui = bar
return display(ui, out)
To start the interactivity, I use the following in a Jupyter notebook:
%matplotlib notebook
from svm_helper import init
init()
So far, I've found adding the following code (from here) in a cell above the cell you have beginning with %matplotlib notebook works:
%%html
<style>
.output_wrapper button.btn.btn-default,
.output_wrapper .ui-dialog-titlebar {
display: none;
}
</style>
Maybe not ideal since instead of explaining to your students to just ignore the buttons, you have to explain why they have to run this, but it's something.

Python matplotlib - set_data and set_3d_properties don't seem to be updating my plot

I am currently working on a Yee Solver script for uni, but when I try to animate my 3D graph, the graph is not what is expected. It works for a 2D plot, but I can't seem to translate that into 3D. From my understanding, set_data and set_3d_properties need a 1D array to work, which I am inputting.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
from matplotlib.widgets import Slider
# Program Variables
wv_lgth_num = 10
graph_type = '3d'
t = 0
# Physical Constants
c = 3e8
mu_r = 1
eps_r = 1
# Source Constants
f = 2e9
omega = 2*f*(np.pi)
amp = 1.0
wv_lgth = c/f
period = 1/f
# Step size
dz = wv_lgth/20
dt = ((c/f)/20)/c
#dt = ((1/f)/20)/1
# Axis Grids
z_grid = np.arange(0,wv_lgth_num*wv_lgth,dz)
t_grid = np.arange(0,10*period,dt)
# Number of steps
num_z = z_grid.size
num_t = t_grid.size
# Coefficients
coe_E = c*dt/(eps_r*dz)
coe_H = c*dt/(mu_r*dz)
# E and H Matricies
E_mat = np.zeros((num_z,num_t))
H_mat = np.zeros((num_z,num_t))
# Generating Values for E and H
for time in range(0,num_t-1):
for pos in range(0,num_z-1):
# Source Wave
if pos == 0:
H_mat[0,time] = amp*np.sin(omega*t_grid[time])
# All cases of Yee Solver
if pos == 1:
if time == 0:
H_mat[1,0] = 0
E_mat[0,0] = 0
else:
H_mat[1,time] = H_mat[1,time-1] + coe_H*(E_mat[1,time-1] - E_mat[0,time-1])
E_mat[0,time] = E_mat[0,time-1] + coe_E*(H_mat[1,time] - H_mat[0,time])
if pos > 1 and pos != num_z-1:
if time == 0:
H_mat[pos,0] = 0
E_mat[pos-1,0] = 0
if time > 0:
H_mat[pos,time] = H_mat[pos,time-1] + coe_H*(E_mat[pos,time-1] - E_mat[pos-1,time-1])
E_mat[pos-1,time] = E_mat[pos-1,time-1] + coe_E*(H_mat[pos,time] - H_mat[pos-1,time])
if pos == num_z-1:
if time == 0:
H_mat[num_z-1,0] = 0
E_mat[num_z-2,0] = 0
E_mat[num_z-1,0] = 0
if time > 0:
H_mat[num_z-1,time] = H_mat[num_z-1,time-1] + coe_H*(E_mat[num_z-1,time-1] - E_mat[num_z-2,time-1])
E_mat[num_z-2,time] = E_mat[num_z-2,time-1] + coe_E*(H_mat[num_z-1,time] - H_mat[num_z-2,time])
E_mat[num_z-1,time] = E_mat[num_z-2,time]
def update(val):
t = slider_time.val
if graph_type == '2d':
a.set_ydata(E_mat[:,t])
b.set_ydata(H_mat[:,t])
if graph_type == '3d':
a.set_3d_properties(E_mat[:,t])
a.set_data(z_grid,np.zeros((num_z,num_t))[:,t])
b.set_3d_properties(np.zeros((num_z,num_t))[:,t])
b.set_data(z_grid,H_mat[:t])
fig.canvas.draw_idle()
print(H_mat)
print(H_mat[:,t].size)
print(z_grid)
print(np.zeros((num_z,num_t))[:,t].size)
# Creating plot
if graph_type == '3d':
fig, ax = plt.subplots()
ax = plt.axes(projection='3d')
b, = ax.plot3D(z_grid,H_mat[:,t],np.zeros((num_z,num_t))[:,t], label='H')
a, = ax.plot3D(z_grid,np.zeros((num_z,num_t))[:,t],E_mat[:,t], label='E')
plt.title('Light Wave')
ax.set_xlabel('z')
ax.set_ylabel('x')
ax.set_zlabel('y')
plt.legend()
ax_time = plt.axes([0.25,0.1,0.65,0.03])
slider_time = Slider(ax_time,'Time',0,num_t-2,valinit=0,valstep=1)
slider_time.on_changed(update)
plt.show()
if graph_type == '2d':
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
a, = plt.plot(z_grid,E_mat[:,t], label='E (yz plane)')
b, = plt.plot(z_grid,H_mat[:,t], label='H (xz plane)')
plt.title('Light Wave')
plt.xlabel('z')
plt.ylabel('x')
plt.legend()
ax_time = plt.axes([0.25,0.1,0.65,0.03])
slider_time = Slider(ax_time,'Time',0,num_t-2,valinit=0,valstep=1)
slider_time.on_changed(update)
plt.show()
Any help would be appreciated. The middle for loop is just generating my functions, using the Yee Method.

How to use vispy to generate a rolling image?

Some context:
I was looking into the vispy module to plot in realtime (or as close as possible to) data coming from an instrument. My attempt follow.
from vispy.plot import Fig
from vispy import app,scene
from vispy.visuals import TextVisual
import numpy as np
import Queue
FONT_SIZE = 14
MIN = 0
MAX = 1.1
w_size = 100
N = 5000
M = 2500
color_map = 'cubehelix'
q_size = 1000
Nb = 5
#generate (empty) initial data to fill the plot
data = np.zeros(N*M)
data = np.reshape(data, (N,M))
#setup the plot
fig = Fig(show = False,size = (16*w_size,9*w_size),bgcolor='black')
fig.title = 'my plot'
main_plot = fig[0,0].image(data = data,fg_color='w',cmap=color_map,clim=(MIN,MAX))
fig[0,0].view.camera.aspect = N/float(M) * 16./9.
title = scene.Label("someoutput", font_size=FONT_SIZE, color = 'w')
fig[0,0].grid.add_widget(title, row=0, col=4)
fig[0,0].grid[2,4].border_color = 'black'
fig[0,0].grid[2,4].bgcolor = 'black'
xlabel_title = scene.Label("x_axis [unit]", font_size=FONT_SIZE, color = 'w')
fig[0,0].grid.add_widget(xlabel_title, row=4, col=4)
ylabel_title = scene.Label("y_axis [unit]", font_size=FONT_SIZE,rotation=-90, color='w')
fig[0,0].grid.add_widget(ylabel_title, row=2, col=2)
scale = scene.ColorBarWidget(orientation='left',
cmap=color_map,
label='Some value',
clim=(MIN,MAX),
border_color = 'w',
border_width = 1,
label_color = 'w'
)
fig[0,0].grid.add_widget(scale, row=2, col=6)
fig[0,0].cbar_right.width_max = \
fig[0,0].cbar_right.width_min = 50
#fill a queue so to excude the generation time from the plotting time
q = Queue.Queue()
for i in range(q_size):
new_data = (np.abs(0.5*np.random.randn(Nb*M)[:])).astype('float32')
new_data = np.reshape(new_data, (Nb,M))
q.put(new_data[:])
#update function
def update(ev):
global main_plot, q, data, Nb,M,fig,index
#acquire
new_data = q.get()
#roll the plot data
data[Nb:, :] = data[:-Nb, :]
data[:Nb,:] = new_data
#recycle the new data
q.put(new_data)
#update the plot
main_plot.set_data(data)
main_plot.update()
# setup timer
interv = 0.01
timer = app.Timer(interval = interv)
timer.connect(update)
timer.start(interval = interv)
if __name__ == '__main__':
fig.show(run=True)
app.run()
This code currently works but it's much slower than the data rate. In the vispy gallery, as well as in some examples, I saw much more points being plotted and updated. I think that the main problem is that I completely set each time all the data of the plot instead of shifting them and inserting new points.
I also had a look at this example:
https://github.com/vispy/vispy/blob/master/examples/demo/scene/oscilloscope.py
However I don't know how to generalize the update function that rolls the data (I have no knowledge of OpenGL) and I cannot use the example as is because I need a quantitative color scale (that seems well implemented in vispy.plot).
The question:
Is there a way to write a function that rolls the data of a plot generated with the vispy.plot class?
Thanks.

matplotlib figure parameters don't appears

Here is my issue: I have an embedded matplotlib figure in a Qt5 application. When I press the button "edit axis, curve and image parameter", I select my concerned subplot, but only the tab "axis" options appears. it is missing tabs for "curve" and "image".
actual picture
whereas I should have had something like this:
targeted picture
If anyone knows why...
Probably the answer is easy:
If there is no curve (line) in the plot, there will be no "Curves" tab.
If there is no image in the plot, there will be no "Images" tab.
class View2D(MapView):
def show(self, som, what='codebook', which_dim='all', cmap=None,
col_sz=None, desnormalize=False):
(self.width, self.height, indtoshow, no_row_in_plot, no_col_in_plot,
axis_num) = self._calculate_figure_params(som, which_dim, col_sz)
self.prepare()
if not desnormalize:
codebook = som.codebook.matrix
else:
codebook = som._normalizer.denormalize_by(som.data_raw, som.codebook.matrix)
if which_dim == 'all':
names = som._component_names[0]
elif type(which_dim) == int:
names = [som._component_names[0][which_dim]]
elif type(which_dim) == list:
names = som._component_names[0][which_dim]
while axis_num < len(indtoshow):
axis_num += 1
ax = plt.subplot(no_row_in_plot, no_col_in_plot, axis_num)
ind = int(indtoshow[axis_num-1])
min_color_scale = np.mean(codebook[:, ind].flatten()) - 1 * np.std(codebook[:, ind].flatten())
max_color_scale = np.mean(codebook[:, ind].flatten()) + 1 * np.std(codebook[:, ind].flatten())
min_color_scale = min_color_scale if min_color_scale >= min(codebook[:, ind].flatten()) else \
min(codebook[:, ind].flatten())
max_color_scale = max_color_scale if max_color_scale <= max(codebook[:, ind].flatten()) else \
max(codebook[:, ind].flatten())
norm = matplotlib.colors.Normalize(vmin=min_color_scale, vmax=max_color_scale, clip=True)
mp = codebook[:, ind].reshape(som.codebook.mapsize[0],
som.codebook.mapsize[1])
# pl = plt.pcolor(mp[::-1], norm=norm, cmap='jet')
pl = plt.imshow(mp[::-1], interpolation='nearest', origin='lower',cmap='jet')
plt.axis([0, som.codebook.mapsize[1], 0, som.codebook.mapsize[0]])
plt.title(names[axis_num - 1])
ax.set_yticklabels([])
ax.set_xticklabels([])
plt.colorbar(pl)
plt.show()

Categories