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()
Related
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.
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.
When I run my code I create a figure, then I create a subplot in that figure. Then when I try to add a title to it using ax.set_title("title") it sometimes shows up for a split second then goes away. I have tried using plot.title aswell with no luck.
I tried recreating the error in a small example but for some reason it worked just fine there, so here is the entire source code of the code.
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.style as style
import plotgen
from matplotlib.widgets import Button
class plotWindow():
def __init__(self):
style.use("bmh")
self.dp = 30
self.fig = plt.figure()
self.ax = self.fig.add_subplot(1, 1, 1, label="ax1")
self.cax = 1
self.maxax = 2
self.minax = 1
plotgen.clear("plot1.txt")
plotgen.clear("plot2.txt")
axnext = plt.axes([0.80, 0.01, 0.06, 0.06])
axprev = plt.axes([0.73, 0.01, 0.06, 0.06])
bnext = Button(axnext, 'Next >')
bnext.on_clicked(self.changePlotNext)
bprev = Button(axprev, "< Previous")
bprev.on_clicked(self.changePlotPrev)
ani = animation.FuncAnimation(self.fig, self.animate, interval=500)
plt.show()
def changePlotNext(self, i):
if self.cax < self.maxax:
self.cax += 1
self.ax.set_title("Pump " + str(self.cax))
def changePlotPrev(self, i):
if self.cax > self.minax:
self.cax -= 1
self.ax.set_title("Pump " + str(self.cax))
def animate(self, i):
if self.cax == 1:
plotgen.generate("plot1.txt")
graph_data = open('plot1.txt', 'r').read()
lines = graph_data.split('\n')
xs = []
ys = []
for line in lines:
if len(line) > 1:
x, y = line.split(',')
xs.append(x)
ys.append(float(y))
self.ax.clear()
lx = len(xs)
ly = len(ys)
if len(xs) < self.dp:
pxs = xs
pys = ys
else:
pxs = xs[(lx - (self.dp - 1)):(lx - 1)]
pys = ys[(ly - (self.dp - 1)):(ly - 1)]
self.ax.plot(pxs, pys, "r")
elif self.cax == 2:
plotgen.generate("plot2.txt")
graph_data = open('plot2.txt', 'r').read()
lines = graph_data.split('\n')
xs = []
ys = []
for line in lines:
if len(line) > 1:
x, y = line.split(',')
xs.append(x)
ys.append(float(y))
self.ax.clear()
lx = len(xs)
ly = len(ys)
if len(xs) <= self.dp:
pxs = xs
pys = ys
else:
pxs = xs[(lx - (self.dp - 1)):(lx - 1)]
pys = ys[(ly - (self.dp - 1)):(ly - 1)]
self.ax.plot(pxs, pys)
plotWindow()
As you can see in my changePlotNext and changePlotPrev functions I'm trying to change the title. Sometimes they display for a split second when I change, but then it goes away. And I am very aware that I have not set a title to display before I change the plot.
In animate, you have self.ax.clear(), which is removing all artists, texts, etc. on the Axes, including the title.
A simple option, then, is to reset the title after you clear the axes. So if you add:
self.ax.set_title("Pump " + str(self.cax))
in both places, immediately after you call self.ax.clear(), your titles will still be shown.
Another option would be to stop clearing the axes, but just remove the items you need to remove. I think this is just the lines you have plotted? So, for example, you could remove the call to self.ax.clear(), and add:
for line in self.ax.lines:
line.remove()
in its place. That will remove just the plotted line, but retain the title.
I'd like to create a barplot in matplotlib:
fig, ax = plt.subplots()
oldbar = ax.bar(x=ind, height=y, width=width)
I'd then like to pickle this barplot to file (either the dictionary or the axes - I'm not sure which is correct):
pickle.dump(oldbar, file('oldbar.pkl', 'w'))
I'd then like to reload this file, and then plot the old bar onto alongside a new bar plot, so I can compare them on a single axes:
fig, ax = plt.subplots()
newbar = ax.bar(x=ind, height=y, width=width)
oldbar = pickle.load(file('oldbar.pkl'))
# I realise the line below doesn't work
ax.bar(oldbar)
plt.show()
Ideally, I'd then like to present them as below. Any suggestions of how I might go about this?
You would pickle the figure instead the artists in it.
import matplotlib.pyplot as plt
import numpy as np
import pickle
ind = np.linspace(1,5,5)
y = np.linspace(9,1,5)
width = 0.3
fig, ax = plt.subplots()
ax.bar(x=ind, height=y, width=width)
ax.set_xlabel("x label")
pickle.dump(fig, file('oldbar.pkl', 'w'))
plt.close("all")
ind2 = np.linspace(1,5,5)
y2 = np.linspace(8,2,5)
width2 = 0.3
fig2 = pickle.load(file('oldbar.pkl'))
ax2 = plt.gca()
ax2.bar(x=ind2+width, height=y2, width=width2, color="C1")
plt.show()
However pickling the data itself may make more sense here.
import matplotlib.pyplot as plt
import numpy as np
import pickle
ind = np.linspace(1,5,5)
y = np.linspace(9,1,5)
width = 0.3
dic = {"ind":ind, "y":y, "width":width}
pickle.dump(dic, file('olddata.pkl', 'w'))
### new data
ind2 = np.linspace(1,5,5)
y2 = np.linspace(8,2,5)
width2 = 0.3
olddic = pickle.load(file('olddata.pkl'))
fig, ax = plt.subplots()
ax.bar(x=olddic["ind"], height=olddic["y"], width=olddic["width"])
ax.bar(x=ind2+olddic["width"], height=y2, width=width2)
ax.set_xlabel("x label")
plt.show()
Maybe this will help:
import pickle as pkl
import matplotlib.pyplot as plt
import numpy as np
class Data_set(object):
def __init__(self, x=[], y=[], name='data', pklfile=None,
figure=None, axes=None):
"""
"""
if pklfile is None:
self.x = np.asarray(x)
self.y = np.asarray(y)
self.name = str(name)
else:
self.unpickle(pklfile)
self.fig = figure
self.ax = axes
self.bar = None
def plot(self, width=0, offset=0, figure=None, axes=None):
if self.fig is None:
if figure is None:
self.fig = plt.figure()
self.ax = self.fig.subplots(1, 1)
else:
self.fig = figure
if axes is None:
self.ax = self.fig.subplots(1, 1)
else:
self.ax = axes
# maybe there's no need to keep track of self.fig, .ax and .bar,
# but just in case...
if figure is not None:
fig_to_use = figure
if axes is not None:
ax_to_use = axes
else:
ax_to_use = fig_to_use.subplots(1, 1)
else:
fig_to_use = self.fig
ax_to_use = self.ax
if not width:
width = (self.x[1]-self.x[0]) / 2.
self.bar = ax_to_use.bar(x=self.x+offset, height=self.y, width=width)
return fig_to_use, ax_to_use, self.bar
def pickle(self, filename='', ext='.pkl'):
if filename == '':
filename = self.name
with open(filename+ext, 'w') as output_file:
pkl.dump((self.name, self.x, self.y), output_file)
def unpickle(self, filename='', ext='.pkl'):
if filename == '':
filename = self.name
with open(filename + ext, 'r') as input_file:
# the name should really come from the filename, but then the
# above would be confusing?
self.name, self.x, self.y = pkl.load(input_file)
class Data_set_manager(object):
def __init__(self, datasets={}):
self.datasets = datasets
def add_dataset(self, data_set):
self.datasets[data_set.name] = data_set
def add_dataset_from_file(self, filename, ext='.pkl'):
self.datasets[filename] = Data_set(name=filename)
self.datasets[filename].unpickle(filename=filename, ext=ext)
def compare(self, width=0, offset=0, *args):
self.fig = plt.figure()
self.ax = self.fig.subplots(1, 1)
if len(args) == 0:
args = self.datasets.keys()
args.sort()
n = len(args)
if n == 0:
return None, None
if width == 0:
min_dx = None
for dataset in self.datasets.values():
sorted_x = dataset.x.copy()
sorted_x.sort()
try:
new_min_dx = np.min(dataset.x[1:] - dataset.x[:-1])
except ValueError:
# zero-size array to reduction operation minimum which
# has no identity (empty array)
new_min_dx = None
if new_min_dx < min_dx or min_dx is None:
min_dx = new_min_dx
if min_dx is None:
min_dx = 1.
width = float(min_dx) / (n + 1)
offset = float(min_dx) / (n + 1)
offsets = offset*np.arange(n)
if n % 2 == 0:
offsets -= offsets[n/2] - offset/2.
else:
offsets -= offsets[n/2]
i = 0
for name in args:
self.datasets.get(name, Data_set()).plot(width=width,
offset=offsets[i],
figure=self.fig,
axes=self.ax)
i += 1
self.ax.legend(args)
return self.fig, self.ax
if __name__ == "__main__":
# test saving/loading
name = 'test'
to_pickle = Data_set(x=np.arange(10),
y=np.random.rand(10),
name=name)
to_pickle.pickle()
unpickled = Data_set(pklfile=name)
print unpickled.name == to_pickle.name
# test comparison
blorg = Data_set_manager({})
x_step = 1.
n_bars = 4 # also try an odd number
for n in range(n_bars):
blorg.add_dataset(Data_set(x=x_step * np.arange(n_bars),
y=np.random.rand(n_bars),
name='teste' + str(n)))
fig, ax = blorg.compare()
fig.show()
It should work with both even and odd number of bars:
And as long as you keep a record of the names you've used (tip:look in the folder where you are saving them) you can reload the data and compare it with the new one.
More checks could be made (to make sure the file exists, that the x axis is something that can be subtracted before trying to do so, etc.), and it could also use some documentation and proper testing - but this should do in a hurry.
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)