Dynamical plot with Chaco - python

I need to add some points to an existent plot I do in chaco. I have tried with plot.request_redraw() but it didn't work. What else can I do?
This is the piece of code:
class PlotApp(HasTraits):
plotdata = Instance(ArrayPlotData)
returns_plot = Instance(Plot)
plot_type = Enum('line', 'scatter')
corr_renderer = Any()
x_min = Float()
x_max = Float()
traits_view = View(
VGroup(
HGroup(spring, Label('Click point to select/unselect'),
spring),
#Item('plot_type'),
Item('returns_plot', editor=ComponentEditor(size=size,
bgcolor=bg_color),
show_label=False),
#Item('num_medicion', width=-225),
orientation = "vertical"),
resizable=True, title=title
)
def _create_returns_plot(self):
plot = Plot(self.plotdata)
plot.legend.visible = True
plot.x_axis = None
x_axis = PlotAxis(plot, orientation="bottom")
plot.overlays.append(x_axis)
renderer = plot.plot(("index", "value"), type="scatter",name = "Mediciones")[0]
#Agrego todas las tools necesarias
renderer.tools.append(ScatterInspector(renderer, selection_mode="toggle", persistent_hover=False))
renderer.overlays.append(
ScatterInspectorOverlay(renderer,
hover_color = "transparent",
hover_marker_size = 10,
hover_outline_color = "purple",
hover_line_width = 2,
selection_marker_size = 8,
selection_color = "red")
)
renderer.tools.append(RangeSelection(renderer, left_button_selects = False, disable_left_mouse = True, \
rigth_button_selects = True, \
auto_handle_event = False, metadata_name = "annotations"))
renderer.overlays.append(RangeSelectionOverlay(component=renderer, metadata_name = "annotations"))
renderer.tools.append(PanTool(renderer))
renderer.overlays.append(ZoomTool(renderer, drag_button="right"))
self.index_datasource = renderer.index
self.index_datasource.on_trait_change(self._selections_changed, "metadata_changed")
self.returns_plot = plot
def _create_data(self):
#genero los datos, más adelante los voy a leer con pandas
npts = 40
x_max = 10
x = np.random.random(npts)
x = x * x_max
error = np.random.random(npts)
y = 2 + 3*x + 5*error
#Esta parte es para ordenar los elementos
x_ordenado = np.array([])
y_ordenado = np.array([])
orden = range(x.size)
nuevo_orden = np.array([])
for i in range(x.size):
arg_min = x.argmin()
x_ordenado = np.append(x_ordenado, x[arg_min])
y_ordenado = np.append(y_ordenado, y[arg_min])
nuevo_orden = np.append(nuevo_orden, orden[arg_min])
x = np.delete(x, arg_min)
y = np.delete(y, arg_min)
orden = np.delete(orden, arg_min)
self.x_ordenado = x_ordenado
self.y_ordenado = y_ordenado
#Genero el retorno para el plot
plotdata = ArrayPlotData()
plotdata.set_data("index", x_ordenado)
plotdata.set_data("value", y_ordenado)
self.plotdata = plotdata
def _selections_changed(self):
#Obtengo los puntos marcados manualmente
self.posicion_puntos_selec = self.index_datasource.metadata.get('selections', ())
#obtengo los puntos que marque con el rectangulo
seleccionado_range = self.index_datasource.metadata.get('annotations', ())
#Cuando desmarcon con el rectangu, el tipo de annotations es NoneType,
#con este if lo cambio a tuple
type_range = type(self.index_datasource.metadata['annotations'])
if type_range != tuple:
self.index_datasource.metadata['annotations'] = []
else:
self.x_min, self.x_max = seleccionado_range
#on_trait_change("posicion_puntos_selec, x_min, x_max")
def _perform_calculations(self):
plot = self.returns_plot
x_nuevo = np.append(self.x_calcular, [11, 12])
y_nuevo = np.append(self.y_calcular, [11, 12])
self.corr_renderer = plot.plot((x_nuevo, y_nuevo),
type="scatter", color="blue")[0]
plot.request_redraw()

To update the data of an existing plot, the best and simplest is to update the existing ArrayPlotData of the existing Plot instance being displayed. There are listeners inside Chaco that will take care of the redraw. Below is an example inspired from your code:
from traits.api import HasTraits, Enum, Instance, Button
from traitsui.api import View, Item, VGroup
from enable.api import ComponentEditor
from chaco.api import Plot, ArrayPlotData, PlotAxis
from numpy import arange
class PlotApp(HasTraits):
plotdata = Instance(ArrayPlotData)
returns_plot = Instance(Plot)
plot_type = Enum('line', 'scatter')
add_points = Button
traits_view = View(
VGroup(Item("add_points"),
Item('returns_plot', editor=ComponentEditor(),
show_label=False),
orientation = "vertical"),
resizable=True, title="Test"
)
def _returns_plot_default(self):
self.plotdata = ArrayPlotData(index=arange(100), value=arange(100))
plot = Plot(self.plotdata)
plot.legend.visible = True
plot.x_axis = None
x_axis = PlotAxis(plot, orientation="bottom")
plot.overlays.append(x_axis)
plot.plot(("index", "value"), type="scatter", name = "Mediciones")
return plot
def _add_points_fired(self):
current_length = len(self.plotdata["index"])
self.plotdata.set_data("index", arange(current_length+1))
self.plotdata.set_data("value", arange(current_length+1))
if __name__ == "__main__":
app = PlotApp()
app.configure_traits()
HTH,
Jonathan

Related

How to change the view of this graph with NetworkX?

I have this code but the way it generates the reports is not intuitive for the visualization with multiple data combined. What changes should I make so that the graph shows me a scale to measure or a way to group the values with more interactions?
The current output is:
The expected output is
# ------------------------------------------------------------
# packages
# ------------------------------------------------------------
import numpy as np
import pandas as pd
import os
import glob
import re
import matplotlib.pyplot as plt
import networkx as nx
# ------------------------------------------------------------
# Funcoes
# ------------------------------------------------------------
from readidlist import readIdList
from extrafuns import *
# ------------------------------------------------------------
def getgrapho():
# lendo a lista dos IDs e nome dos pesquisadores
df_idlist = readIdList()
# df_idlist['ID_LATTES'] = df_idlist['ID_LATTES'].apply(ss)
# config_file = open('./config.txt', 'r')
config_file = open('./config.txt', 'r', encoding='utf-8')
yyi = config_file.readlines()[5].split(':')[1]
yyi = yyi.rstrip('\n')
yyi = yyi.strip(' ')
yyi = float(yyi)
config_file.close()
# config_file = open('./config.txt', 'r')
config_file = open('./config.txt', 'r', encoding='utf-8')
yyf = config_file.readlines()[6].split(':')[1]
yyf = yyf.rstrip('\n')
yyf = yyf.strip(' ')
yyf = float(yyf)
config_file.close()
# ------------------------------------------------------------
# importadando os data frames gerados pelo gettidy
# ------------------------------------------------------------
dfppe_uniq = pd.read_csv('./csv_producao/projetos_uniq.csv',
header=0)
dfpaper = pd.read_csv('./csv_producao/periodicos_all.csv',
header=0)
dfpaper_uniq = pd.read_csv('./csv_producao/periodicos_uniq.csv',
header=0)
# paper uniq
dfpaper['ID'] = dfpaper['ID'].apply(ss)
dfpaper_uniq['ID'] = dfpaper_uniq['ID'].apply(ss)
# filtrando o ano
# projetos
dfppe_uniq['YEAR_INI'] = dfppe_uniq['YEAR_INI'].replace('VAZIO', -99)
num99 = dfppe_uniq[dfppe_uniq['YEAR_INI'] == -99]
if len(num99) >= 1:
print('------------------------------------------------------------')
print('ATENCAO: ' + str(len(num99)) + 'projetos sem ano inicial')
print('------------------------------------------------------------')
dfppe_uniq['YEAR_INI'] = dfppe_uniq['YEAR_INI'].apply(ff)
dfppe_uniq = dfppe_uniq[(dfppe_uniq['YEAR_INI'] >= yyi)]
# ------------------------------------------------------------
# periodicos
dfpaper['YEAR'] = dfpaper['YEAR'].replace('VAZIO', -99)
dfpaper_uniq['YEAR'] = dfpaper_uniq['YEAR'].replace('VAZIO', -99)
num99 = dfpaper[dfpaper['YEAR'] == -99]
if len(num99) >= 1:
print('------------------------------------------------------------')
print('ATENCAO: ' + str(len(num99)) + 'artigos sem ano de publicacao')
print('------------------------------------------------------------')
dfpaper['YEAR'] = dfpaper['YEAR'].apply(ff)
dfpaper_uniq['YEAR'] = dfpaper_uniq['YEAR'].apply(ff)
dfpaper = dfpaper[(dfpaper['YEAR'] >= yyi) & (dfpaper['YEAR'] <= yyf)]
dfpaper_uniq = dfpaper_uniq[(dfpaper_uniq['YEAR']
>= yyi) & (dfpaper_uniq['YEAR'] <= yyf)]
# ------------------------------------------------------------
# ordenando por ano (crescente)
dfppe_uniq_pesq = dfppe_uniq[dfppe_uniq['NATUREZA'] == 'PESQUISA']
dfppe_uniq_pesq = dfppe_uniq_pesq.sort_values(['YEAR_INI'])
dfppe_uniq_ext = dfppe_uniq[dfppe_uniq['NATUREZA'] == 'EXTENSAO']
dfppe_uniq_ext = dfppe_uniq_ext.sort_values(['YEAR_INI'])
dfpaper = dfpaper.sort_values(['YEAR'])
dfpaper_uniq = dfpaper_uniq.sort_values(['YEAR'])
# ------------------------------------------------------------
# carregando df com dados pessoais
lscsv_fullname = glob.glob('./csv_producao/*fullname.csv')
# df com nome completo, sobrenome e id
dffullname = pd.DataFrame()
for i in range(len(lscsv_fullname)):
a = pd.read_csv(lscsv_fullname[i], header=0, dtype='str')
dffullname = dffullname.append(a, ignore_index=False)
# passando ID para string, para poder comparar com dfpaper
dffullname['ID'] = dffullname['ID'].apply(ss)
dffullname = dffullname.reset_index(drop=True)
# verificando a interacao de periodicos entre integrantes
lsid = []
lsid_tocompare = []
lsinter_qtd = []
for m in range(len(df_idlist)):
idd = str(df_idlist.iloc[m, 0])
lname = dffullname[dffullname['ID'] == idd]
lname = lname.iloc[0, 1]
lname = lname.upper()
# lname = lname.split(';')
# print(lname)
dfids_tocompare = dffullname[dffullname['ID'] != str(idd)]
for n in range(len(dfids_tocompare)):
idd_tocompare = dfids_tocompare.iloc[n, 0]
dd = dfpaper[dfpaper['ID'] == idd_tocompare]
lsid.append(str(idd))
lsid_tocompare.append(idd_tocompare)
# DANGER ATTENTION FIX lname deve ser o nome completo
# removendo caract desnecessarios
interac = 0
for o in range(len(dd)):
authors = dd['AUTHOR'].iloc[o].upper()
authors = authors.replace('[', '')
authors = authors.replace(']', '')
authors = authors.replace("'", '')
authors = authors.split(',')
# print(authors)
for op in range(len(authors)):
# print(authors[op])
if len(authors[op]) > 0:
if authors[op][0] == ' ':
authors[op] = authors[op][1:]
# interac = 0
inpaper = list(set([lname]) & set(authors))
if len(inpaper) >= 1:
interac = interac + 1
# print(interac)
# print(lname)
# print(authors)
lsinter_qtd.append(interac)
dfinterac = pd.DataFrame({'IDD': lsid,
'IDD_COMP': lsid_tocompare,
'WEIGHT': lsinter_qtd})
# data frame para profissionais sem interacao em periodicos
lsnointer_period = []
for m in range(len(df_idlist)):
aano = dfinterac[dfinterac['IDD'] == df_idlist.iloc[m, 0]]
aasum = aano['WEIGHT'].sum()
aano_a = dfinterac[dfinterac['IDD_COMP'] == df_idlist.iloc[m, 0]]
aasum_a = aano_a['WEIGHT'].sum()
if aasum == 0 and aasum_a == 0:
nointer = dffullname[dffullname['ID'] ==
df_idlist.iloc[m, 0]].reset_index(drop=True)
nointer = nointer.iloc[0, 1]
lsnointer_period.append(nointer)
dfnointerac = pd.DataFrame({'NOME': lsnointer_period})
dfnointerac.to_csv('./csv_producao/periodicos_nointer.csv',
index=False, sep=',')
# DANGER ATTENTION
# dfinterac.to_csv('test.csv', index=False)
# eliminando linhas sem interacao
indexremove = []
for i in range(len(lsid)):
if lsinter_qtd[i] == 0:
indexremove.append(i)
for index in sorted(indexremove, reverse=True):
del lsid[index]
del lsid_tocompare[index]
del lsinter_qtd[index]
# ------------------------------------------------------------
# Grapho
plt.figure(figsize=(12, 9.5))
G = nx.Graph()
for i in range(len(lsid)):
G.add_edge(lsid[i],
lsid_tocompare[i],
weight=lsinter_qtd[0])
pos = nx.spring_layout(G, 1.75)
# colors for nodes
colours = ['#5a7d9a', 'red', 'green', 'yellow',
'gray', 'orange', 'blue', 'magenta',
'#00555a', '#f7d560', 'cyan', '#b6b129',
'#a1dd72', '#d49acb', '#d4a69a', '#977e93',
'#a3cc72', '#c60acb', '#d4b22a', '#255e53',
'#77525a', '#c7d511', '#c4c22b', '#c9b329',
'#c8dd22', '#f75acb', '#b1a40a', '#216693',
'#b1cd32', '#b33acb', '#c9a32b', '#925e11',
'#c5dd39', '#d04205', '#d8a82a', '#373e29']
lsgroup_uniq = df_idlist['GROUP'].unique()
dic_colours = {}
for i in range(len(lsgroup_uniq)):
dic_colours[lsgroup_uniq[i]] = colours[i]
a = list(G.nodes())
node_colours = []
for i in range(len(a)):
x = df_idlist[df_idlist['ID_LATTES'] == a[i]]
x = x.iloc[0, 2]
c = dic_colours[x]
node_colours.append(c)
# nodes
nx.draw_networkx_nodes(G, pos,
node_size=400,
node_shape='o',
node_color=node_colours,
alpha=0.7)
# labels
nn = list(G.nodes)
diclabel = {}
for i in range(len(nn)):
x = df_idlist[df_idlist['ID_LATTES'] == nn[i]]
xid = x.iloc[0, 0]
xname = x.iloc[0, 1]
diclabel[str(xid)] = xname
# edges
nx.draw_networkx_edges(G, pos, # edgelist=lsinter_qtd,
width=1, edge_color='orange')
# labels
nx.draw_networkx_labels(G, pos, labels=diclabel, font_size=16,
font_family='sans-serif')
plt.axis('off')
plt.tight_layout()
plt.savefig('./relatorio/figures/grapho.png')
# plt.show()
# ------------------------------------------------------------
# ------------------------------------------------------------
# Com pesos
# ------------------------------------------------------------
# G = nx.Graph()
# for i in range(len(lsid)):
# G.add_edge(lsid[i], lsid_tocompare[i], weight=lsinter_qtd[0])
# # elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] > 3]
# # esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d['weight'] <= 3]
# pos = nx.spring_layout(G) # positions for all nodes
# # nodes
# nx.draw_networkx_nodes(G, pos,
# node_size=400,
# node_shape='o',
# node_color=node_colours)
# # label = lsinter_qtd)
# # edges
# nx.draw_networkx_edges(G, pos, # edgelist=lsinter_qtd,
# width=1, edge_color='orange')
# # nx.draw_networkx_edges(G, pos, edgelist=elarge,
# # width=1, edge_color='orange')
# # nx.draw_networkx_edges(G, pos, edgelist=esmall,
# # width=1, arrowsize=30, alpha=0.5,
# # edge_color='b', style='dashed')
# # labels
# nx.draw_networkx_labels(G, pos, labels=diclabel,
# font_size=14, font_family='sans-serif')
# plt.axis('off')
# plt.show()
# ------------------------------------------------------------
Some solution for this problem

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.

MPC with python and Error ValueError: `f0` passed has more than 1 dimension

I wrote a MPC with Python and it worked before. After a long time I want to use it again but I got this Error
f0 passed has more than 1 dimension.
But I didn't change anything on my code. It is some kind of strange.
Here is my code:
import numpy as np
import numpy.linalg as npl
import matplotlib.pyplot as plt
from scipy.optimize import minimize
def mpcAugment(Am, Bm, Cm ):
"Function for Augmented Model"
nx, nu = Bm.shape
ny = Cm.shape[0]
A = np.zeros((nx+ny,nx+ny))
A[0:nx,0:nx] = Am
A[nx:nx+ny,0:nx] = Cm#Am
A[nx:nx+ny,nx:nx+ny] = np.eye(ny)
B = np.zeros((nx+ny,nu))
B[0:nx,:nu] = Bm
B[nx:nx+ny,:nu] = Cm#Bm
C = np.zeros((ny,nx+ny))
C[:ny,nx:nx+ny] = np.eye(ny)
return A, B, C
'Define Parameters'
k = 0.4
AICB = 153.8
mcp = 8.8e4
vamb1 = 30
vamb2 = 45
a = -k*AICB/mcp
b = -1/mcp
Ts = 20
VICBref = -5.0
Am = np.array([[1+Ts*a]])
Bm = np.array([[Ts*b]])
Gm = np.array([[-Ts*a]])
Cm = np.array([[1]])
A, B, C = mpcAugment(Am,Bm,Cm)
A, G, C = mpcAugment(Am,Gm,Cm)
nx, nu = B.shape
ny = C.shape[0]
nd = G.shape[1]
Np = 20
Nu = 5
F = np.zeros((Np*ny,nx))
PHI = np.zeros((Np*ny,Nu*nu))
PHIw = np.zeros((Np*ny,Np*nd))
for i in range(0,Np):
Ai = npl.matrix_power(A, i+1)
F[i*ny:(i+1)*ny,:] = C#Ai
for j in range(0, Nu):
if j <= i:
Aij = np.linalg.matrix_power(A, i-j)
PHI[i*ny:(i+1)*ny, j*nu:(j+1)*nu] = C#Aij#B
for j in range(0, Np):
if j <= i:
Aij = np.linalg.matrix_power(A, i-j)
PHIw[i*ny:(i+1)*ny, j*nd:(j+1)*nd] = C#Aij#G
umax = 3100
umin = 0
Q = np.eye(Np*ny)
R = 1e-2*np.eye(Nu*nu)
Rs = VICBref*np.ones((Np*ny,1))
Ainq = np.zeros((2*Nu*nu,Nu*nu))
binq = np.zeros((2*Nu*nu,1))
cinq = np.zeros((2*Nu*nu,1))
for i in range(0,Nu):
binq[i*nu:(i+1)*nu] = umax
binq[(i+Nu)*nu:(Nu+i+1)*nu] = 1
cinq[i*nu:(i+1)*nu] = 1
cinq[(i+Nu)*nu:(Nu+i+1)*nu] = -1
for j in range(0,i+1):
Ainq[i*nu:(i+1)*nu,j*nu:(j+1)*nu] = np.eye(nu)
Ainq[(i+Nu)*nu:(Nu+i+1)*nu,j*nu:(j+1)*nu] = np.eye(nu)
u0 = 0
def objective(du):
dU = np.array(du).reshape((len(du),1))
Y = F#x + PHI#dU + PHIw#w
return np.transpose((Rs-Y))#(Rs-Y)+np.transpose(dU)#R#(dU)
def constraint1(du):
dU = np.array(du).reshape((len(du),1))
return (binq - Ainq#dU - cinq*u0)[0]
#print(objective([1,1,1]))
ulim = (umin, umax)
bnds = np.kron(np.ones((Nu,1)),ulim)
#print(bnds)
Um = np.ones((nu*Nu,1))
Tsim = 5e4
time = np.arange(0,Tsim,Ts)
Nt = len(time)
xm = np.zeros((Nt,1))
um = np.zeros((Nt,nu))
ym = np.zeros((Nt,ny))
xm[0] = 0
ym[0] = Cm.dot(xm[0])
w = np.zeros((Np*nd,1))
print('Am = ',Am)
print('Bm = ',Bm)
print('Cm = ',Cm)
x = np.zeros((nx,1))
x[1] = xm[0]
vamb = vamb1
Vamb = np.zeros((Nt,1))
Ns = int(np.floor(Nt/2))
Vamb[0:Ns] = vamb1*np.ones((Ns,1))
Vamb[Ns:Nt] = vamb2*np.ones((Nt-Ns,1))
Vref = VICBref*np.ones((Nt,1))
con = {'type':'ineq','fun':constraint1}
for i in range(0,Nt-1):
sol = minimize(objective, Um, method = 'SLSQP',constraints = con)
if sol.success == False:
print('Error Cant solve problem')
exit()
Um = sol.x
um[i+1] = um[i] + Um[0]
u0 = um[i+1]
xm[i+1] = Am.dot(xm[i])+Bm.dot(um[i+1])+Gm.dot(Vamb[i])
ym[i+1] = Cm.dot(xm[i+1])
for j in range(0,Np):
if i+j < Nt:
Rs[j] = Vref[i+j]
w[j] = Vamb[i+j]-Vamb[i+j-1]
else:
Rs[j] = Vref[Nt-1]
w[j] = 0
x[0] = xm[i+1] - xm[i]
x[1] = xm[i+1]
print('Q = ',um[i+1],' , VICB = ',xm[i+1], ' vamb = ', Vamb[i])
hour = 60*60
plt.figure()
plt.subplot(2,1,1)
plt.plot(time/hour,ym)
plt.plot(time/hour,Vref,'--')
plt.xlabel('time(hours)')
plt.xlim([0, Tsim/hour])
plt.subplot(2,1,2)
plt.plot(time/hour,um)
plt.xlim([0, Tsim/hour])
plt.show()
It about a controller, which control the temperature of a cool box.
Is that possible that anything changed in main simply code?
I think the problem is now in minimizations part.
I reinstalled all of my libraries and it worked

How to Draw an 2d Array

How could I graph this array u,
import math
import numpy as np
import matplotlib.pyplot as plt
pi=np.arccos(-1)
#Parameters En la ecuación del calor 1D
L = 1.;
T =1.;
#Parámetros del método
maxk = 2500; # Divisiones temporales
dt = T/maxk;
n = 50; # Divisiones espaciales
dx = L/n;
cond = 1/4; # Conductividad
b = 2.*cond*dt/(dx*dx); # Alpha
u=[[None]*maxk]*n
x=[None]*n
time=[None]*maxk
# Suponga temperatura distribuida de forma senoidal en la varilla para t=0
for i in range(0,n):
x[i] =i*dx;
u[i][0] =np.sin( pi*x[i] );
# Suponga una frontera a temperatura cero
for k in range(0,maxk):
u[0][k] = 0.;
u[n-1][k] = 0.;
time[k] = k*dt;
#Metodo explicito de solucion
for k in range(0,maxk-1):
for i in range(1, n-2):
u[i][k+1] =u[i][k] + 0.5*b*u[i-1][k]+u[i+1][k]-2.*u[i][k];
fig = plt.figure(figsize=(16, 13.2))
ax = fig.add_subplot(111)
ax.set_title('colorMap')
plt.imshow(u)
ax.set_aspect('equal')
cax = fig.add_axes([0.12, 0.1, 0.78, 0.8])
cax.get_xaxis().set_visible(False)
cax.get_yaxis().set_visible(False)
cax.patch.set_alpha(0)
cax.set_frame_on(False)
plt.colorbar(orientation='vertical')
plt.show()
I would expect a result like this
but I get something like this

3D Surface Streaming in Plotly

I am trying to generate a 3D surface using Plotly's streaming API and I receive no errors in the actual Python code however I get the "Oops! An error occured while loading this plot's data" on Plotly. Here is my code:
import plotly.plotly as py
import plotly.tools as tls
import plotly.graph_objs as go
from random import uniform
import pandas as pd
import time
tls.set_credentials_file(username='', api_key='')
stream_id = tls.get_credentials_file()['stream_ids']
token = stream_id[-1]
stream_id = dict(token=token)
z = []
surface = go.Surface(z=z, stream=stream_id)
data = [surface]
layout = go.Layout(
title='Test',
autosize=False,
width=500,
height=500,
margin=dict(
l=65,
r=50,
b=65,
t=90
)
)
fig = go.Figure(data=data, layout=layout)
plot_url = py.iplot(fig, filename='elevations-3d-surface', auto_open=True)
s = py.Stream(stream_id=token)
s.open()
matrices = []
for p in range(5):
matrix = []
for x in range(25):
row = []
for y in range(25):
row.append(uniform(25, 100))
matrix.append(row)
test = pd.DataFrame(matrix)
print(test)
matrices.append(matrix)
print(pd.DataFrame(matrices[1]))
i = 0
while True:
step = 3
z = matrices[i]
s.write(go.Surface(z=z))
time.sleep(step)
i += 1
if i == len(matrices):
i = 0
print(i)
# print(pd.DataFrame(z))
s.close()
Got it work, here is my final code:
import plotly.plotly as py
import plotly.tools as tls
import plotly.graph_objs as go
import scipy.ndimage as ndimage
from random import uniform
import pandas as pd
import numpy as np
import time
tls.set_credentials_file(username='', api_key='')
stream_id = tls.get_credentials_file()['stream_ids']
token = stream_id[-1]
stream_id = dict(token=token)
z_init = np.zeros(100).reshape((10, 10))
z = z_init
surface = go.Surface(z=z, stream=stream_id)
data = [surface]
layout = go.Layout(
title='Test',
autosize=False,
width=500,
height=500,
margin=dict(
l=65,
r=50,
b=65,
t=90
)
)
fig = go.Figure(data=data, layout=layout)
plot_url = py.iplot(fig, filename='', auto_open=True)
s = py.Stream(stream_id=token)
s.open()
arr_width = 25
arr_length = 25
matrices = []
for p in range(100):
matrix = []
for x in range(arr_width):
row = []
for y in range(arr_length):
row.append(uniform(-1, 1))
matrix.append(row)
matrices.append(matrix)
##################################################################
# given 2 arrays arr1, arr2, number of steps between arrays, and order of interpolation
# numpoints = 10
# order = 2
# arr1 = matrices[1]
# arr2 = matrices[2]
def interp(arr1, arr2, numpoints, order):
# rejoin arr1, arr2 into a single array of shape (2, 10, 10)
arr = np.r_['0, 3', arr1, arr2]
# define the grid coordinates where you want to interpolate
X, Y = np.meshgrid(np.arange(arr_width), np.arange(arr_length))
k = 0
interp_arr_vec = []
while k <= 1:
coordinates = np.ones((arr_width, arr_length))*k, X, Y
# given arr interpolate at coordinates
interp_arr = ndimage.map_coordinates(arr, coordinates, order=order).T
interp_arr_vec.append(interp_arr)
step = 1 / numpoints
k += step
return interp_arr_vec
##################################################################
sleep_time = .1
i = 0
while True:
between_test = interp(matrices[i], matrices[i+1], 200, 3)
r = 0
for r in range(len(between_test)):
s.write(go.Surface(z=between_test[r]))
time.sleep(sleep_time)
i += 1
print('i = ', i)
time.sleep(3)
if i == len(matrices):
i = 0
s.close()

Categories