Using units in mathjax and asciimathml - mathjax
We're using MathJax to render ASCIIMathML equations with units of measure. We have found a situation where MathJax is being too clever for our own good...
3.14 in
renders as...
3.14 ∈
where ∈ is the set membership symbol.
Any suggestions on turning that cleverness off? The doc has some options but none that seem to cover this use case.
These are student entered strings so we can't ask them to understand the nuances of MathJax.
Thanks!
Jim
How about 3.14 text{in} or 3.14 text{ in} if you want a space between the number and unit?
Since you trying to use AsciiMath for student input, one approach would be to limit the number of commands that are available. For example, you can modify the symbol list to remove the ones you don't want. One approach would be to simply replace the list with a new one that contains only the ones you want (this may be the easiest way). For example, you could put the following code in your page just before the script tag that loads MathJax.js itself.
<script type="text/x-mathjax-config">
MathJax.Hub.Register.StartupHook("AsciiMath Jax Config",function () {
var AM = MathJax.InputJax.AsciiMath.AM;
var CONST = AM.TOKEN.CONST,
UNARY = AM.TOKEN.UNARY,
BINARY = AM.TOKEN.BINARY,
INFIX = AM.TOKEN.INFIX,
TEXT = AM.TOKEN.TEXT,
DEFINITION = AM.TOKEN.DEFITION,
UNDEROVER = AM.TOKEN.UNDEROVER,
LEFTRIGHT = AM.TOKEN.LEFTRIGHT,
LEFTBRACKET = AM.TOKEN.LEFTBRACKET,
RIGHTBRACKET = AM.TOKEN.RIGHTBRACKET;
AM.symbols.splice(0,AM.symbols.length,
{input:"*", tag:"mo", output:"\u22C5", tex:"cdot", ttype:CONST},
{input:"-:", tag:"mo", output:"\u00F7", tex:"div", ttype:CONST},
{input:"divide", tag:"mo", output:"-:", tex:null, ttype:DEFINITION},
{input:"!=", tag:"mo", output:"\u2260", tex:"ne", ttype:CONST},
{input:"lt", tag:"mo", output:"<", tex:null, ttype:CONST},
{input:"<=", tag:"mo", output:"\u2264", tex:"le", ttype:CONST},
{input:"lt=", tag:"mo", output:"\u2264", tex:"leq", ttype:CONST},
{input:"gt", tag:"mo", output:">", tex:null, ttype:CONST},
{input:">=", tag:"mo", output:"\u2265", tex:"ge", ttype:CONST},
{input:"gt=", tag:"mo", output:"\u2265", tex:"geq", ttype:CONST},
//grouping brackets
{input:"(", tag:"mo", output:"(", tex:null, ttype:LEFTBRACKET},
{input:")", tag:"mo", output:")", tex:null, ttype:RIGHTBRACKET},
{input:"[", tag:"mo", output:"[", tex:null, ttype:LEFTBRACKET},
{input:"]", tag:"mo", output:"]", tex:null, ttype:RIGHTBRACKET},
{input:"{", tag:"mo", output:"{", tex:null, ttype:LEFTBRACKET},
{input:"}", tag:"mo", output:"}", tex:null, ttype:RIGHTBRACKET},
{input:"|", tag:"mo", output:"|", tex:null, ttype:LEFTRIGHT},
{input:"(:", tag:"mo", output:"\u2329", tex:"langle", ttype:LEFTBRACKET},
{input:":)", tag:"mo", output:"\u232A", tex:"rangle", ttype:RIGHTBRACKET},
{input:"<<", tag:"mo", output:"\u2329", tex:null, ttype:LEFTBRACKET},
{input:">>", tag:"mo", output:"\u232A", tex:null, ttype:RIGHTBRACKET},
{input:"{:", tag:"mo", output:"{:", tex:null, ttype:LEFTBRACKET, invisible:true},
{input:":}", tag:"mo", output:":}", tex:null, ttype:RIGHTBRACKET, invisible:true},
//miscellaneous symbols
{input:"+-", tag:"mo", output:"\u00B1", tex:"pm", ttype:CONST},
{input:"O/", tag:"mo", output:"\u2205", tex:"emptyset", ttype:CONST},
{input:"oo", tag:"mo", output:"\u221E", tex:"infty", ttype:CONST},
{input:"...", tag:"mo", output:"...", tex:"ldots", ttype:CONST},
{input:"'", tag:"mo", output:"\u2032", tex:"prime", ttype:CONST},
{input:"CC", tag:"mo", output:"\u2102", tex:null, ttype:CONST},
{input:"NN", tag:"mo", output:"\u2115", tex:null, ttype:CONST},
{input:"QQ", tag:"mo", output:"\u211A", tex:null, ttype:CONST},
{input:"RR", tag:"mo", output:"\u211D", tex:null, ttype:CONST},
{input:"ZZ", tag:"mo", output:"\u2124", tex:null, ttype:CONST},
{input:"f", tag:"mi", output:"f", tex:null, ttype:UNARY, func:true},
{input:"g", tag:"mi", output:"g", tex:null, ttype:UNARY, func:true},
//standard functions
{input:"lim", tag:"mo", output:"lim", tex:null, ttype:UNDEROVER},
{input:"Lim", tag:"mo", output:"Lim", tex:null, ttype:UNDEROVER},
{input:"sin", tag:"mo", output:"sin", tex:null, ttype:UNARY, func:true},
{input:"cos", tag:"mo", output:"cos", tex:null, ttype:UNARY, func:true},
{input:"tan", tag:"mo", output:"tan", tex:null, ttype:UNARY, func:true},
{input:"sinh", tag:"mo", output:"sinh", tex:null, ttype:UNARY, func:true},
{input:"cosh", tag:"mo", output:"cosh", tex:null, ttype:UNARY, func:true},
{input:"tanh", tag:"mo", output:"tanh", tex:null, ttype:UNARY, func:true},
{input:"cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true},
{input:"sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true},
{input:"csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true},
{input:"arcsin", tag:"mo", output:"arcsin", tex:null, ttype:UNARY, func:true},
{input:"arccos", tag:"mo", output:"arccos", tex:null, ttype:UNARY, func:true},
{input:"arctan", tag:"mo", output:"arctan", tex:null, ttype:UNARY, func:true},
{input:"coth", tag:"mo", output:"coth", tex:null, ttype:UNARY, func:true},
{input:"sech", tag:"mo", output:"sech", tex:null, ttype:UNARY, func:true},
{input:"csch", tag:"mo", output:"csch", tex:null, ttype:UNARY, func:true},
{input:"exp", tag:"mo", output:"exp", tex:null, ttype:UNARY, func:true},
{input:"abs", tag:"mo", output:"abs", tex:null, ttype:UNARY, rewriteleftright:["|","|"]},
{input:"log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true},
{input:"ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true},
{input:"gcd", tag:"mo", output:"gcd", tex:null, ttype:UNARY, func:true},
{input:"lcm", tag:"mo", output:"lcm", tex:null, ttype:UNARY, func:true},
{input:"min", tag:"mo", output:"min", tex:null, ttype:UNDEROVER},
{input:"max", tag:"mo", output:"max", tex:null, ttype:UNDEROVER},
//arrows
{input:"uarr", tag:"mo", output:"\u2191", tex:"uparrow", ttype:CONST},
{input:"darr", tag:"mo", output:"\u2193", tex:"downarrow", ttype:CONST},
{input:"rarr", tag:"mo", output:"\u2192", tex:"rightarrow", ttype:CONST},
{input:"->", tag:"mo", output:"\u2192", tex:"to", ttype:CONST},
{input:">->", tag:"mo", output:"\u21A3", tex:"rightarrowtail", ttype:CONST},
{input:"->>", tag:"mo", output:"\u21A0", tex:"twoheadrightarrow", ttype:CONST},
{input:">->>", tag:"mo", output:"\u2916", tex:"twoheadrightarrowtail", ttype:CONST},
{input:"|->", tag:"mo", output:"\u21A6", tex:"mapsto", ttype:CONST},
{input:"larr", tag:"mo", output:"\u2190", tex:"leftarrow", ttype:CONST},
{input:"harr", tag:"mo", output:"\u2194", tex:"leftrightarrow", ttype:CONST},
{input:"rArr", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST},
{input:"lArr", tag:"mo", output:"\u21D0", tex:"Leftarrow", ttype:CONST},
{input:"hArr", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST},
//commands with argument
{input:"sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY},
{input:"root", tag:"mroot", output:"root", tex:null, ttype:BINARY},
{input:"frac", tag:"mfrac", output:"/", tex:null, ttype:BINARY},
{input:"/", tag:"mfrac", output:"/", tex:null, ttype:INFIX},
{input:"_", tag:"msub", output:"_", tex:null, ttype:INFIX},
{input:"^", tag:"msup", output:"^", tex:null, ttype:INFIX},
{input:"text", tag:"mtext", output:"text", tex:null, ttype:TEXT},
{input:"color", tag:"mstyle", ttype:BINARY},
{input:"cancel", tag:"menclose", output:"cancel", tex:null, ttype:UNARY}
);
});
</script>
It would also be possible to turn this into a configuration file that you could load rather than having to include it in each page directly.
I'm not sure all these are appropriate for your situation, but you can remove the ones you don't think are appropriate. Just be sure that you don't leave an extra comma at the end of the last one in the list
Finally, if you want things like "in" to be able to be used for inches, then you could add commands for them, like
{input:"in", tag:"mtext", output:"\u2006in", tex:null, ttype:CONST},
say at the top of the list. (Here the \u2006 is a character that represents a small amount of space.) You may need to include several other forms, as well, such as
{input:"in", tag:"mtext", output:"\u2006in", tex:null, ttype:CONST},
{input:"inch", tag:"mtext", output:"\u2006in", tex:null, ttype:CONST},
{input:"inches", tag:"mtext", output:"\u2006in", tex:null, ttype:CONST},
Include whatever units you might need.
Related
Matplotlib Scatter plot interactivity not working
Until this morning I was able to display labels information when hovering the dots on a scatter plot. Now, if I run the following code it does not display any error but the interactivity is not working and it looks like mplconnect or mlpcursors are completely ignored. I've tried the same code under windows and Fedora. Not understanding what's going on. from matplotlib.pyplot import figure, show import numpy as npy from numpy.random import rand x, y, c, s = rand(4, 100) def onpick3(event): ind = event.ind print('onpick3 scatter:', ind, npy.take(x, ind), npy.take(y, ind)) fig = figure() ax1 = fig.add_subplot(111) col = ax1.scatter(x, y, 100*s, c, picker=True) #fig.savefig('pscoll.eps') fig.canvas.mpl_connect('pick_event', onpick3) show() Or import matplotlib.pyplot as plt import numpy as np; np.random.seed(1) x = np.random.rand(15) y = np.random.rand(15) names = np.array(list("ABCDEFGHIJKLMNO")) c = np.random.randint(1,5,size=15) norm = plt.Normalize(1,4) cmap = plt.cm.RdYlGn fig,ax = plt.subplots() sc = plt.scatter(x,y,c=c, s=100, cmap=cmap, norm=norm) annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->")) annot.set_visible(False) def update_annot(ind): pos = sc.get_offsets()[ind["ind"][0]] annot.xy = pos text = "{}, {}".format(" ".join(list(map(str,ind["ind"]))), " ".join([names[n] for n in ind["ind"]])) annot.set_text(text) annot.get_bbox_patch().set_facecolor(cmap(norm(c[ind["ind"][0]]))) annot.get_bbox_patch().set_alpha(0.4) def hover(event): vis = annot.get_visible() if event.inaxes == ax: cont, ind = sc.contains(event) if cont: update_annot(ind) annot.set_visible(True) fig.canvas.draw_idle() else: if vis: annot.set_visible(False) fig.canvas.draw_idle() fig.canvas.mpl_connect("motion_notify_event", hover) plt.show() This is not my code, I've copied and pasted it from a website but the behavior is the same.
Plotly express solves the problem import plotly.express as px alpha = data[data['Ticker']==focus].V1 gamma = data[data['Ticker']==focus].V2 fig = px.scatter(data, x='V1', y='V2', color=Colors.Market_Cap, hover_data=["Ticker"] ) fig.add_shape(type="circle", xref="x", yref="y", x0=int(alpha-3), y0=int(gamma-3), x1=int(alpha+3), y1=int(gamma+3), line_color="LightSeaGreen", ) fig.show()
Graph Disconnected when implementing custom LSTM
I've been trying to write my own LSTM for customization. However, an error occurred when I try to call my code using Keras. The error said the graph was disconnected on c_prev, but c_prev was used as LSTM's cell initializer. So I'm not sure if it's something wrong with my code or the way I call the model. Any help is appreciated. My environment: Python 3.7.6 Tensorflow 2.1.0 (installed via pip) Mac Mojave class EtienneLSTM(tf.keras.layers.Layer): def __init__(self, units, activation='tanh', recurrent_activation='sigmoid', kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', use_bias=True, unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, # dropout=0.0, recurrent_dropout=0.0, return_sequences=False, return_state=False, go_backwards=False, use_batchnorm=False): super(EtienneLSTM, self).__init__() self.units = units # self.activation = tf.keras.layers.Activation(activation) # self.recurrent_activation = tf.keras.layers.Activation(recurrent_activation) # self.use_bias = use_bias # self.kernel_initializer = kernel_initializer # self.recurrent_initializer = recurrent_initializer # self.bias_initializer = bias_initializer # self.unit_forget_bias = unit_forget_bias # if self.unit_forget_bias: self.bias_initializer = 'zeros' self.kernel_regularizer = kernel_regularizer # self.recurrent_regularizer = recurrent_regularizer # self.bias_regularizer = bias_regularizer # self.activity_regularizer = activity_regularizer self.kernel_constraint = kernel_constraint # self.recurrent_constraint = recurrent_constraint # self.bias_constraint = bias_constraint # # self.dropout = dropout # self.recurrent_dropout = recurrent_dropout self.return_sequences = return_sequences # self.return_state = return_state # self.go_backwards = go_backwards # self.use_batchnorm = use_batchnorm if self.use_batchnorm: self.batchnorm_f = tf.keras.layers.BatchNormalization() self.batchnorm_i = tf.keras.layers.BatchNormalization() self.batchnorm_o = tf.keras.layers.BatchNormalization() self.batchnorm_c = tf.keras.layers.BatchNormalization() def build(self, input_shape): # forgot gate self.Wf = self.add_weight(shape=(input_shape[-1], self.units), initializer=self.kernel_initializer, regularizer=self.kernel_regularizer, constraint=self.kernel_constraint, trainable=True) self.Uf = self.add_weight(shape=(self.units, self.units), initializer=self.recurrent_initializer, regularizer=self.recurrent_regularizer, constraint=self.recurrent_constraint, trainable=True) if self.unit_forget_bias: self.bf = self.add_weight(shape=(self.units,), initializer='ones', regularizer=self.bias_regularizer, constraint=self.bias_constraint, trainable=True) else: self.bf = self.add_weight(shape=(self.units,), initializer=self.bias_initializer, regularizer=self.bias_regularizer, trainable=True) # input gate self.Wi = self.add_weight(shape=(input_shape[-1], self.units), initializer=self.kernel_initializer, regularizer=self.kernel_regularizer, constraint=self.kernel_constraint, trainable=True) self.Ui = self.add_weight(shape=(self.units, self.units), initializer=self.recurrent_initializer, regularizer=self.recurrent_regularizer, constraint=self.recurrent_constraint, trainable=True) if self.use_bias: self.bi = self.add_weight(shape=(self.units,), initializer=self.bias_initializer, regularizer=self.bias_regularizer, constraint=self.bias_constraint, trainable=True) # output gate self.Wo = self.add_weight(shape=(input_shape[-1], self.units), initializer=self.kernel_initializer, regularizer=self.kernel_regularizer, constraint=self.kernel_constraint, trainable=True) self.Uo = self.add_weight(shape=(self.units, self.units), initializer=self.recurrent_initializer, regularizer=self.recurrent_regularizer, constraint=self.recurrent_constraint, trainable=True) if self.use_bias: self.bo = self.add_weight(shape=(self.units,), initializer=self.bias_initializer, regularizer=self.bias_regularizer, constraint=self.bias_constraint, trainable=True) # context self.Wc = self.add_weight(shape=(input_shape[-1], self.units), initializer=self.kernel_initializer, regularizer=self.kernel_regularizer, constraint=self.kernel_constraint, trainable=True) self.Uc = self.add_weight(shape=(self.units, self.units), initializer=self.recurrent_initializer, regularizer=self.recurrent_regularizer, constraint=self.recurrent_constraint, trainable=True) if self.use_bias: self.bc = self.add_weight(shape=(self.units,), initializer=self.bias_initializer, regularizer=self.bias_regularizer, constraint=self.bias_constraint, trainable=True) def _inp_gate(self, x, hidden): return self.recurrent_activation(tf.matmul(x, self.Wi) + tf.matmul(hidden, self.Ui) + self.bi) def _new_mem(self, x, hidden): return self.activation(tf.matmul(x, self.Wc) + tf.matmul(hidden, self.Uc) + self.bc) def _forget_gate(self, x, hidden): return self.recurrent_activation(tf.matmul(x, self.Wf) + tf.matmul(hidden, self.Uf) + self.bf) def _update_cell(self, c_prev, c_tilde, f_t, i_t): return (f_t * c_prev) + (i_t * c_tilde) def _out_gate(self, x, hidden, ct): ot = self.recurrent_activation(tf.matmul(x, self.Wo) + tf.matmul(hidden, self.Uo) + self.bo) return ot * self.activation(ct) def call(self, x, hidden, c_prev): if self.go_backwards: x = x[:,:,::-1] f_t = self._forget_gate(x, hidden) i_t = self._inp_gate(x, hidden) c_tilde = self._new_mem(x, hidden) c_t = self._update_cell(c_prev, c_tilde, f_t, i_t) h_t = self._out_gate(x, hidden, c_t) # if self.return_state: # return h_t, c_t # if self.return_sequences: # return h_t return h_t tf.keras.backend.clear_session() def get_LSTM(): inp = tf.keras.layers.Input(shape=(200, 40)) out = tf.keras.layers.LSTM(32)(inp) return tf.keras.Model(inp, out) def get_EtienneLSTM(): inp = tf.keras.layers.Input(shape=(200, 40)) h0 = tf.keras.layers.Input(shape=(32,), name='h0') c0 = tf.keras.layers.Input(shape=(32,), name='c0') out = EtienneLSTM(32)(inp, h0, c0) return tf.keras.Model(inp, out) model_tf = get_LSTM() model_etienne = get_EtienneLSTM() Here is my error message: --------------------------------------------------------------------------- ValueError Traceback (most recent call last) in 14 15 model_tf = get_LSTM() ---> 16 model_etienne = get_EtienneLSTM() in get_EtienneLSTM() 11 c0 = tf.keras.layers.Input(shape=(32,), name='c0') 12 out = EtienneLSTM(32)(inp, h0, c0) ---> 13 return tf.keras.Model(inp, out) 14 15 model_tf = get_LSTM() ~/.env/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/training.py in __init__(self, *args, **kwargs) 144 145 def __init__(self, *args, **kwargs): --> 146 super(Model, self).__init__(*args, **kwargs) 147 _keras_api_gauge.get_cell('model').set(True) 148 # initializing _distribution_strategy here since it is possible to call ~/.env/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/network.py in __init__(self, *args, **kwargs) 167 'inputs' in kwargs and 'outputs' in kwargs): 168 # Graph network --> 169 self._init_graph_network(*args, **kwargs) 170 else: 171 # Subclassed network ~/.env/lib/python3.7/site-packages/tensorflow_core/python/training/tracking/base.py in _method_wrapper(self, *args, **kwargs) 455 self._self_setattr_tracking = False # pylint: disable=protected-access 456 try: --> 457 result = method(self, *args, **kwargs) 458 finally: 459 self._self_setattr_tracking = previous_value # pylint: disable=protected-access ~/.env/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/network.py in _init_graph_network(self, inputs, outputs, name, **kwargs) 322 # Keep track of the network's nodes and layers. 323 nodes, nodes_by_depth, layers, _ = _map_graph_network( --> 324 self.inputs, self.outputs) 325 self._network_nodes = nodes 326 self._nodes_by_depth = nodes_by_depth ~/.env/lib/python3.7/site-packages/tensorflow_core/python/keras/engine/network.py in _map_graph_network(inputs, outputs) 1674 'The following previous layers ' 1675 'were accessed without issue: ' + -> 1676 str(layers_with_complete_input)) 1677 for x in nest.flatten(node.output_tensors): 1678 computable_tensors.add(id(x)) ValueError: Graph disconnected: cannot obtain value for tensor Tensor("c0:0", shape=(None, 32), dtype=float32) at layer "c0". The following previous layers were accessed without issue: ['input_2'] Thank you for your help.
Resolved, it seems that I implement LSTM wrong way. The correct method of implementing LSTM is as follows: class EtienneLSTM(tf.keras.layers.Layer): def __init__(self, units, activation='tanh', recurrent_activation='sigmoid', kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', use_bias=True, unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, # dropout=0.0, recurrent_dropout=0.0, return_sequences=False, return_state=False, go_backwards=False, use_batchnorm=False): super(EtienneLSTM, self).__init__() self.units = units # self.activation = tf.keras.layers.Activation(activation) # self.recurrent_activation = tf.keras.layers.Activation(recurrent_activation) # self.use_bias = use_bias # self.kernel_initializer = kernel_initializer # self.recurrent_initializer = recurrent_initializer # self.bias_initializer = bias_initializer # self.unit_forget_bias = unit_forget_bias # if self.unit_forget_bias: self.bias_initializer = 'zeros' self.kernel_regularizer = kernel_regularizer # self.recurrent_regularizer = recurrent_regularizer # self.bias_regularizer = bias_regularizer # self.activity_regularizer = activity_regularizer self.kernel_constraint = kernel_constraint # self.recurrent_constraint = recurrent_constraint # self.bias_constraint = bias_constraint # # self.dropout = dropout # self.recurrent_dropout = recurrent_dropout self.return_sequences = return_sequences # self.return_state = return_state # self.go_backwards = go_backwards # self.use_batchnorm = use_batchnorm if self.use_batchnorm: self.batchnorm_f = tf.keras.layers.BatchNormalization() self.batchnorm_i = tf.keras.layers.BatchNormalization() self.batchnorm_o = tf.keras.layers.BatchNormalization() self.batchnorm_c = tf.keras.layers.BatchNormalization() def build(self, input_shape): # forgot gate self.Wf = self.add_weight(shape=(input_shape[-1], self.units), initializer=self.kernel_initializer, regularizer=self.kernel_regularizer, constraint=self.kernel_constraint, trainable=True) self.Uf = self.add_weight(shape=(self.units, self.units), initializer=self.recurrent_initializer, regularizer=self.recurrent_regularizer, constraint=self.recurrent_constraint, trainable=True) if self.unit_forget_bias: self.bf = self.add_weight(shape=(self.units,), initializer='ones', regularizer=self.bias_regularizer, constraint=self.bias_constraint, trainable=True) else: self.bf = self.add_weight(shape=(self.units,), initializer=self.bias_initializer, regularizer=self.bias_regularizer, trainable=True) # input gate self.Wi = self.add_weight(shape=(input_shape[-1], self.units), initializer=self.kernel_initializer, regularizer=self.kernel_regularizer, constraint=self.kernel_constraint, trainable=True) self.Ui = self.add_weight(shape=(self.units, self.units), initializer=self.recurrent_initializer, regularizer=self.recurrent_regularizer, constraint=self.recurrent_constraint, trainable=True) if self.use_bias: self.bi = self.add_weight(shape=(self.units,), initializer=self.bias_initializer, regularizer=self.bias_regularizer, constraint=self.bias_constraint, trainable=True) # output gate self.Wo = self.add_weight(shape=(input_shape[-1], self.units), initializer=self.kernel_initializer, regularizer=self.kernel_regularizer, constraint=self.kernel_constraint, trainable=True) self.Uo = self.add_weight(shape=(self.units, self.units), initializer=self.recurrent_initializer, regularizer=self.recurrent_regularizer, constraint=self.recurrent_constraint, trainable=True) if self.use_bias: self.bo = self.add_weight(shape=(self.units,), initializer=self.bias_initializer, regularizer=self.bias_regularizer, constraint=self.bias_constraint, trainable=True) # context self.Wc = self.add_weight(shape=(input_shape[-1], self.units), initializer=self.kernel_initializer, regularizer=self.kernel_regularizer, constraint=self.kernel_constraint, trainable=True) self.Uc = self.add_weight(shape=(self.units, self.units), initializer=self.recurrent_initializer, regularizer=self.recurrent_regularizer, constraint=self.recurrent_constraint, trainable=True) if self.use_bias: self.bc = self.add_weight(shape=(self.units,), initializer=self.bias_initializer, regularizer=self.bias_regularizer, constraint=self.bias_constraint, trainable=True) def _inp_gate(self, x, hidden): return self.recurrent_activation(tf.matmul(x, self.Wi) + tf.matmul(hidden, self.Ui) + self.bi) def _new_mem(self, x, hidden): return self.activation(tf.matmul(x, self.Wc) + tf.matmul(hidden, self.Uc) + self.bc) def _forget_gate(self, x, hidden): return self.recurrent_activation(tf.matmul(x, self.Wf) + tf.matmul(hidden, self.Uf) + self.bf) def _update_cell(self, c_prev, c_tilde, f_t, i_t): return (f_t * c_prev) + (i_t * c_tilde) def _out_gate(self, x, hidden, ct): ot = self.recurrent_activation(tf.matmul(x, self.Wo) + tf.matmul(hidden, self.Uo) + self.bo) return ot * self.activation(ct) def step_function(self, x_t, states): h_t, c_t = states f_t = self._forget_gate(x_t, h_t) i_t = self._inp_gate(x_t, h_t) c_tilde = self._new_mem(x_t, h_t) c_t = self._update_cell(c_t, c_tilde, f_t, i_t) h_t = self._out_gate(x_t, h_t, c_t) return h_t, [h_t, c_t] def call(self, x): if self.go_backwards: x = x[:,:,::-1] h_init = tf.zeros((tf.shape(x)[0], self.units)) c_init = tf.zeros((tf.shape(x)[0], self.units)) h, H, c = tf.keras.backend.rnn(self.step_function, x, (h_init, c_init)) if self.return_state: return h, c if self.return_sequences: return H return h This is referring this question. tf.keras.backend.rnn needed to be used.
First tkinter program
I'm relatively new to the whole tkinter/python thing and I've just created the following Calculator: import tkinter as tk class theCalculator: def __init__(self, master): master.wm_title("Calculator") master.geometry("340x350") master.resizable(0, 0) signsList = ["-","+","*","/","%"] #Declaring the buttons self.textField = tk.Entry(master, width=16, font=("Arial Bold",20)) self.textField.place(x=40,y=50) self.cButton = tk.Button(master, text="C", width=14, height=2, command = lambda:cleanSpace(self)) self.cButton.place(x=40, y=100) self.modButton = tk.Button(master, text="%", width=5, height=2,command=lambda:signThings(self,"%")) self.modButton.place(x=180, y=100) self.divButton = tk.Button(master, text="/", width=5, height=2,command=lambda:signThings(self,"/")) self.divButton.place(x=248, y=100) self.xButton = tk.Button(master, text="x", width=5, height=2, bg="yellow",command=lambda:signThings(self,"*")) self.xButton.place(x=248, y=142) self.minusButton = tk.Button(master, text="-", width=5, height=2, bg="yellow",command=lambda:signThings(self,"-")) self.minusButton.place(x=248, y=185) self.plusButton = tk.Button(master, text="+", width=5, height=2, bg ="yellow",command=lambda:signThings(self,"+")) self.plusButton.place(x=248, y=228) self.nineButton = tk.Button(master, text="9", width=5, height=2,command=lambda:setText(self,"9")) self.nineButton.place(x=40, y=142) self.eightButton = tk.Button(master, text="8", width=5, height=2,command=lambda:setText(self,"8")) self.eightButton.place(x=110, y=142) self.sevenButton = tk.Button(master, text="7", width=5, height=2,command=lambda:setText(self,"7")) self.sevenButton.place(x=180, y=142) self.sixButton = tk.Button(master, text="6", width=5, height=2,command=lambda:setText(self,"6")) self.sixButton.place(x=40, y=185) self.fiveButton = tk.Button(master, text="5", width=5, height=2,command=lambda:setText(self,"5")) self.fiveButton.place(x=110, y=185) self.fourButton = tk.Button(master, text="4", width=5, height=2,command=lambda:setText(self,"4")) self.fourButton.place(x=180, y=185) self.threeButton = tk.Button(master, text="3", width=5, height=2,command=lambda:setText(self,"3")) self.threeButton.place(x=40, y=228) self.twoButton = tk.Button(master, text="2", width=5, height=2,command=lambda:setText(self,"2")) self.twoButton.place(x=110, y=228) self.oneButton = tk.Button(master, text="1", width=5, height=2,command=lambda:setText(self,"1")) self.oneButton.place(x=180, y=228) self.zeroButton = tk.Button(master, text="0", width=14, height=2,command=lambda:zeroThings(self)) self.zeroButton.place(x=40, y=271) self.pointButton = tk.Button(master, text=".", width=5, height=2,command=lambda:dotThings(self)) self.pointButton.place(x=180, y=271) self.equalsButton = tk.Button(master, text="=", width=5, height=2, bg="yellow",command=lambda:calculate(self)) self.equalsButton.place(x=248, y=271) #Declaring the methods def setText(self, text): self.textField.insert(tk.END, text) def signThings(self, sign): theText = self.textField.get() if(len(theText)==0): print("The first character can't be a sign") return 0; if(theText[-1] in signsList): print("Can't have two signs one after another") return 0; if(theText[-1]=="."): print("Can't have a sign after .") return 0; self.textField.insert(tk.END, sign) def calculate(self): theResult = eval(self.textField.get()) self.textField.delete(0, tk.END) self.textField.insert(0, str(round(theResult,4))) def cleanSpace(self): self.textField.delete(0, tk.END) def zeroThings(self): theText = self.textField.get() if(len(theText)==1): if(theText==0): print("Can't have two zeroes one after another") else: self.textField.insert(tk.END,"0") elif(len(theText)>1): self.textField.insert(tk.END,"0") def dotThings(self): theText = self.textField.get() numberOfSigns = 0 numberOfDots = 0 for c in theText: if c in signsList: numberOfSigns +=1 if c==".": numberOfDots +=1 try: if (numberOfSigns>=numberOfDots and theText[-1] not in signsList): self.textField.insert(tk.END,".") except Exception as e: self.textField.insert(tk.END,".") root = tk.Tk() calc = theCalculator(root) root.mainloop() I want to ask for your opinions on this and I have some questions: Is there any other way I could have declared the buttons? ie using something like a for loop to create them? I'm pretty sure my "self" game isn't on point. Could you give me some advice on improving it? What is your advice on improving my functions' logic? Please, point out any another flaws you see. Thank you
I am trying to UPDATE a last 10 films watched column in my python code for a basic movie service using sqlite3
In the section of my code where it checks the last digit of the filmswatched variable, I am trying to use the last digit to determine what last film column to place the film name into. However, nothing is being updated into my database. I would greatly appreciate any help with identifying the mistake in my code. Also, you can ignore most of the commented code as its just my failed, but not forgotten, attempts at making a GUI for the service. #importing sqlite so that a database can be made. import sqlite3 #importing tkinter to enable GUI use. import tkinter #importing to time to add sleeps for aesthetics/ from time import sleep #importing re for password check import re ##Using sqlite to create a database that holds a table for UserInfo with sqlite3.connect("accounts.db") as db: cursor = db.cursor() cursor.execute("""CREATE TABLE IF NOT EXISTS UserInfo( username text PRIMARY KEY, password text NOT NULL, fullname text NOT NULL, streetname text NOT NULL, city text NOT NULL, postcode text NOT NULL, dob text NOT NULL, gender text NOT NULL, favouritegenre text NOT NULL, filmswatched int NOT NULL, film1 text NOT NULL, film2 text NOT NULL, film3 text NOT NULL, film4 text NOT NULL, film5 text NOT NULL, film6 text NOT NULL, film7 text NOT NULL, film8 text NOT NULL, film9 text NOT NULL, film10 text NOT NULL);""") actionArray = ["1.Die Hard","2.The Matrix","3.The Dark Knight","4.Mad Max","5.Taken","6.Wonder Woman","7.Baby Driver","8.John Wick","9.Logan","10.Thor: Ragnarok"] scifiArray = ["1.Star Wars","2.Star Wars: The Last Jedi","3.E.T. the Extra-Terrestrial","4.Interstellar","5.Star Trek","6.Alien","7.District 9","8.Ex Machina","9.Avatar","WALL-E"] horrorArray = ["1.It","2.Saw","3.Get Out","4.The Shining","5.Nightmare on Elm Street","6.It Follows","7.Halloween","8.The Babadook","9.The Descent","10.The Blair With Project"] db.commit() #Making a main menu. def startup_menu(): window = tkinter.Tk() window.configure(bg="light blue") window.geometry("200x300") signupButton = tkinter.Button(window, text="Sign Up", bg="#4798d1", command=lambda: createUser()) loginButton = tkinter.Button(window, text="Login", bg="#4798d1", command=lambda: login()) signupButton.pack() loginButton.pack() window.mainloop() #Creating a function for creating a new user to be implemented in a startup menu. def createUser(): with sqlite3.connect("accounts.db") as db: cursor = db.cursor() newUsername = input("What is your username: ") newPasswordStatus = False while newPasswordStatus != True: newPassword = input("What is your password (it must have a capital letter and a number): ") if any(c.isupper() for c in newPassword) == True and any(c.isdigit() for c in newPassword) == True: newPasswordStatus = True newName = input("What is your full name: ") newStreetname = input("What is your streetname: ") newCity = input("What is your city: ") newPostcode = input("What is your postcode: ") newDoB = input("What is your date of birt: ") newGender = input("What is your gender: ") newFavouriteGenre = input("What is your favorite genre out of Action, Sci-Fi and Horror: ") cursor.execute("""INSERT INTO UserInfo(username, password, fullname, streetname, city, postcode, dob, gender, favouritegenre, filmswatched, film1, film2, film3, film4, film5, film6, film7, film8, film9, film10)VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?,0,"N/A","N/A","N/A","N/A","N/A","N/A","N/A","N/A","N/A","N/A")""", (newUsername, newPassword, newName, newStreetname, newCity, newPostcode, newDoB, newGender, newFavouriteGenre)) db.commit() cursor.execute("SELECT * FROM UserInfo WHERE username=? AND password=?",(newUsername,newPassword)) print(cursor.fetchall()) print("") startChoice = input("Would you like to:\n 1.Go to the startup menu.\n 2.Create a new user.\n 3.Login as a user.") if startChoice == "1": startup_menu() elif startChoice == "2": createUser() elif startChoice == "3": login() def login(): with sqlite3.connect("accounts.db") as db: global enterUsername enterUsername = input("Username:") global enterPassword enterPassword = input("Password:") cursor.execute("SELECT * FROM UserInfo WHERE username=? and password=?",(enterUsername, enterPassword)) passwordGood = cursor.fetchone() if passwordGood: print("Password is good!") print("") moviebox() else: print("Your password or username was incorrect. Please try again.") login() def moviebox(): with sqlite3.connect("accounts.db") as db: cursor = db.cursor() print("Welcome to the MovieBox service!") print("") print("We have a wide choice of movies to offer you. Pick from our three available genres: Action, Sci-Fi and Horror.") choiceMade = False while choiceMade != True: genreChoice = input("What genre do you want to watch?") genreChoice = genreChoice.lower() if genreChoice == "action": choiceMade = True print("") print("Your choices of movie are: \n",actionArray) movieChoice1 = int(input("What number movie do you want to watch?")) i = movieChoice1 global movieName movieName = actionArray[i-1] movieName = movieName[2:] print("Thank you for watching ",movieName) cursor.execute("UPDATE UserInfo SET filmswatched = filmswatched+1 WHERE username=? AND password=?",(enterUsername, enterPassword)) db.commit() cursor.execute("SELECT filmswatched FROM UserInfo WHERE username=? AND password=?",(enterUsername, enterPassword)) filmswatched = cursor.fetchall() int(filmswatched) print(filmswatched) if filmswatched[-1]==("0"): cursor.execute("""UPDATE film10 WHERE username=? AND password=?",(enterUsername, enterPassword)""", VALUES(movieName,)) db.commit() elif filmswatched[-1]==("1"): cursor.execute("""UPDATE film1 WHERE username=? AND password=?",(enterUsername, enterPassword)""", VALUES(movieName,)) db.commit() elif filmswatched[-1]==("2"): cursor.execute("""UPDATE film2 WHERE username=? AND password=?",(enterUsername, enterPassword)""", VALUES(movieName,)) db.commit() elif filmswatched[-1]==("3"): cursor.execute("""UPDATE film3 WHERE username=? AND password=?",(enterUsername, enterPassword)""", VALUES(movieName,)) db.commit() elif filmswatched[-1]==("4"): cursor.execute("""UPDATE film4 WHERE username=? AND password=?",(enterUsername, enterPassword)""", VALUES(movieName,)) db.commit() elif filmswatched[-1]==("5"): cursor.execute("""UPDATE film5 WHERE username=? AND password=?",(enterUsername, enterPassword)""", VALUES(movieName,)) db.commit() elif filmswatched[-1]==("6"): cursor.execute("""UPDATE film6 WHERE username=? AND password=?",(enterUsername, enterPassword)""", VALUES(movieName,)) db.commit() elif filmswatched[-1]==("7"): cursor.execute("""UPDATE film7 WHERE username=? AND password=?",(enterUsername, enterPassword)""", VALUES(movieName,)) db.commit() elif filmswatched[-1]==("8"): cursor.execute("""UPDATE film8 WHERE username=? AND password=?",(enterUsername, enterPassword)""", VALUES(movieName,)) db.commit() elif filmswatched[-1]==("9"): cursor.execute("""UPDATE film9 WHERE username=? AND password=?",(enterUsername, enterPassword)""", VALUES(movieName,)) db.commit() cursor.execute("SELECT film10 FROM UserInfo WHERE username=? AND password=?",(enterUsername, enterPassword)) result = cursor.fetchall() print(result) sleep(1) moviebox() elif genreChoice == "sci-fi": choiceMade = True print("") print("Your choices of movie are: \n",scifiArray) movieChoice1 = int(input("What number movie do you want to watch?")) i = movieChoice1 movieName = scifiArray[i-1] movieName = movieName[2:] print("Thank you for watching ",movieName) cursor.execute("UPDATE UserInfo SET filmswatched = filmswatched+1 WHERE username=? AND password=?",(enterUsername, enterPassword)) db.commit() cursor.execute("SELECT filmswatched FROM UserInfo WHERE username=? AND password=?",(enterUsername, enterPassword)) filmswatched = cursor.fetchall() elif genreChoice == "horror": choiceMade = True print("") print("Your choices of movie are: \n",horrorArray) movieChoice1 = int(input("What number movie do you want to watch?")) i = movieChoice1 movieName = horrorArray[i-1] movieName = movieName[2:] print("Thank you for watching ",movieName) cursor.execute("UPDATE UserInfo SET filmswatched = filmswatched+1 WHERE username=? AND password=?",(enterUsername, enterPassword)) db.commit() cursor.execute("SELECT filmswatched FROM UserInfo WHERE username=? AND password=?",(enterUsername, enterPassword)) filmswatched = cursor.fetchall() db.commit() #Creating a function for creating a new user through a GUI. ##def create_User(): ## with sqlite3.connect("accounts.db") as db: ## cursor = db.cursor() ## global signup_window ## signup_window = tkinter.Tk() ## signup_window.configure(bg="light blue") ## tkinter.Label(signup_window, text="Here you will create your user.", bg="light blue").pack() ## ## tkinter.Label(signup_window, text="What is your username:", bg="light blue").pack() ## global newUsernameEntry ## newUsernameEntry = tkinter.Entry(signup_window) ## newUsernameEntry.pack() ## global newUsername ## newUsername = newUsernameEntry.get() ## ## ## tkinter.Label(signup_window, text="What is your password (it must have a capital letter and a number):", bg="light blue").pack() ## global newPasswordEntry ## newPasswordEntry = tkinter.Entry(signup_window) ## newPasswordEntry.pack() ## global newPassword ## newPassword = newPasswordEntry.get() ## ## ## ## tkinter.Label(signup_window, text="What is your full name:", bg="light blue").pack() ## global newNameEntry ## newNameEntry = tkinter.Entry(signup_window) ## newNameEntry.pack() ## global newName ## newName = newNameEntry.get() ## ## ## tkinter.Label(signup_window, text="What is your streetname:", bg="light blue").pack() ## global newStreetnameEntry ## newStreetnameEntry = tkinter.Entry(signup_window) ## newStreetnameEntry.pack() ## global newStreetname ## newStreetname = newStreetnameEntry.get() ## ## ## tkinter.Label(signup_window, text="What is your city:", bg="light blue").pack() ## global newCityEntry ## newCityEntry = tkinter.Entry(signup_window) ## newCityEntry.pack() ## global newCity ## newCity = newCityEntry.get() ## ## ## tkinter.Label(signup_window, text="What is your postcode:", bg="light blue").pack() ## global newPostcodeEntry ## newPostcodeEntry = tkinter.Entry(signup_window) ## newPostcodeEntry.pack() ## global newPostcode ## newPostcode = newPostcodeEntry.get() ## ## ## tkinter.Label(signup_window, text="What is your date of birth:", bg="light blue").pack() ## global newDoBEntry ## newDoBEntry = tkinter.Entry(signup_window) ## newDoBEntry.pack() ## global newDoB ## newDoB = newDoBEntry.get() ## ## ## tkinter.Label(signup_window, text="What is your gender:", bg="light blue").pack() ## global newGenderEntry ## newGenderEntry = tkinter.Entry(signup_window) ## newGenderEntry.pack() ## global newGender ## newGender = newGenderEntry.get() ## ## ## tkinter.Label(signup_window, text="What is your favorite genre out of Action, Sci-Fi and Horror:", bg="light blue").pack() ## global newFavouriteGenreEntry ## newFavouriteGenreEntry = tkinter.Entry(signup_window) ## newFavouriteGenreEntry.pack() ## global newFavouriteGenre ## newFavouriteGenre = newFavouriteGenreEntry.get() ## db.commit() ## ## ## tkinter.Button(signup_window, text="Sign Up", bg="#4798d1", command= lambda: signup_check_password()).pack() ##def signup_check_password(): ## global newPasswordStatus ## newPasswordStatus = False ## while newPasswordStatus != True: ## if any(c.isupper() for c in newPasswordEntry.get()) == True and any(c.isdigit() for c in newPasswordEntry.get()) == True: ## newPasswordStatus = True ## newUsername = newUsernameEntry.get() ## newPassword = newPasswordEntry.get() ## newName = newNameEntry.get() ## newStreetname = newStreetnameEntry.get() ## newCity = newCityEntry.get() ## newPostcode = newPostcodeEntry.get() ## newDoB = newDoBEntry.get() ## newGender = newGenderEntry.get() ## newFavouriteGenre = newFavouriteGenreEntry.get() ## with sqlite3.connect("accounts.db") as db: ## cursor = db.cursor() ## cursor.execute("""INSERT INTO UserInfo(username, password, fullname, streetname, city, postcode, dob, gender, favouritegenre)VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)""", ## (newUsername, newPassword, newName, newStreetname, newCity, newPostcode, newDoB, newGender, newFavouriteGenre)) ## db.commit() ## ## signup_window.quit() ## else: ## signup_window.destroy() ## retryWindow = tkinter.Tk() ## retryWindow.configure(bg="light blue") ## tkinter.Label(retryWindow, text="Your password did not meet the requirements. Try again.").pack() ## tkinter.Button(retryWindow, text="OK", command= lambda: create_User()) ##def signup_check_password(): ## global newPasswordStatus ## newPasswordStatus = False ## while newPasswordStatus != True: ## if password_check(newPassword) == True: ## newPasswordStatus = True ## insert_userinfo() ## signup_window.quit() ## else: ## retryWindow = tkinter.Tk() ## retryWindow.configure(bg="light blue") ## tkinter.Label(retryWindow, text="Your password did not meet the requirements. Try again.", bg="light blue").pack() ## tkinter.Button(retryWindow, text="OK", command= lambda: create_User()) ## def password_check(password): if any(c.isupper() for c in newPassword) == True and any(c.isdigit() for c in newPassword) == True: return True else: return False ##def insert_userinfo(): ## with sqlite3.connect("accounts.db") as db: ## cursor = db.cursor() ## cursor.execute("""INSERT INTO UserInfo(username, password, fullname, streetname, city, postcode, dob, gender, favouritegenre)VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)""", ## (newUsername, newPassword, newName, newStreetname, newCity, newPostcode, newDoB, newGender, newFavouriteGenre)) ## cursor.execute("SELECT * FROM UserInfo") ## for x in cursor.fetchall(): ## print(x) startup_menu() db.commit()
How to embed a matplotlib plot with annotation inside Gtk3 window
I trying a lot to place a matplotlib plot (that also uses annotation) to place inside gtk3 window. If there is no annotation, I can place the plot easily inside gtk3. But, I have messed up with how to do it while using annotation. I have tried this without much progress. #!/usr/bin/env python3 import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk import numpy as np import matplotlib.pyplot as plt from matplotlib.figure import Figure from numpy import arange, pi, random, linspace import matplotlib.cm as cm from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas #WINDOW to embede matplotlib x = np.random.rand(15) y = np.random.rand(15) p_window = Gtk.Window() p_window.set_default_size(750,500) p_header = Gtk.HeaderBar() p_window.set_titlebar(p_header) p_header.set_subtitle("Periodic Table") p_header.set_title("column") p_header.set_show_close_button(True) c = np.random.randint(1,50,size=120) norm = plt.Normalize(1,4) cmap = plt.cm.RdYlGn fig,ax = plt.subplots() sc = plt.scatter(x,y) plt.plot(x,y) annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->")) annot.set_visible(False) def update_annot(ind): pos = sc.get_offsets()[ind["ind"][0]] annot.xy = pos namel = "foo" vall = "bar" text = "{}, {}".format(namel[2:-2], vall[1:-1]) annot.set_text(text) # annot.get_bbox_patch().set_facecolor(cmap(norm(c[ind["ind"][0]]))) annot.get_bbox_patch().set_alpha(0.4) def hover(event): vis = annot.get_visible() if event.inaxes == ax: cont, ind = sc.contains(event) if cont: update_annot(ind) annot.set_visible(True) fig.canvas.draw_idle() else: if vis: annot.set_visible(False) fig.canvas.draw_idle() fig.canvas.mpl_connect("motion_notify_event", hover) plt.show() sw = Gtk.ScrolledWindow() p_window.add(sw) canvas = FigureCanvas(fig) canvas.set_size_request(400,400) sw.add_with_viewport(canvas) p_window.show_all() Gtk.main() After removing pyplt I have remove pyplt dependency as suggested, and got this: #!/usr/bin/env python3 import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk import numpy as np # import matplotlib.pyplot as plt from matplotlib.figure import Figure from numpy import arange, pi, random, linspace import matplotlib.cm as cm from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas #WINDOW to embede matplotlib x = np.random.rand(15) y = np.random.rand(15) p_window = Gtk.Window() p_window.set_default_size(750,500) p_header = Gtk.HeaderBar() p_window.set_titlebar(p_header) p_header.set_subtitle("Periodic Table") p_header.set_title("column") p_header.set_show_close_button(True) c = np.random.randint(1,50,size=120) fig = Figure(figsize=(10,6), dpi=100) ax = fig.add_subplot(111) ax.set_ylabel("column") ax.set_xlabel("Z") sc=ax.plot(x,y, "r-o") print(type(fig)) annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->")) annot.set_visible(False) def update_annot(ind): pos = sc.get_offsets()[ind["ind"][0]] annot.xy = pos namel = "foo" vall = "bar" text = "{}, {}".format(namel[2:-2], vall[1:-1]) print(text) annot.set_text(text) # annot.get_bbox_patch().set_facecolor(cmap(norm(c[ind["ind"][0]]))) annot.get_bbox_patch().set_alpha(0.4) def hover(event): vis = annot.get_visible() if event.inaxes == ax: cont, ind = sc.contains(event) if cont: update_annot(ind) annot.set_visible(True) fig.canvas.draw_idle() else: if vis: annot.set_visible(False) fig.canvas.draw_idle() sw = Gtk.ScrolledWindow() p_window.add(sw) canvas = FigureCanvas(fig) canvas.set_size_request(400,400) fig.canvas.mpl_connect("motion_notify_event", hover) sw.add_with_viewport(canvas) p_window.show_all() Gtk.main() which is giving me error: python3 pop.py Traceback (most recent call last): File "/usr/lib64/python3.6/site-packages/matplotlib/backends/backend_gtk3.py", line 268, in motion_notify_event FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event) File "/usr/lib64/python3.6/site-packages/matplotlib/backend_bases.py", line 1958, in motion_notify_event self.callbacks.process(s, event) File "/usr/lib64/python3.6/site-packages/matplotlib/cbook.py", line 549, in process proxy(*args, **kwargs) File "/usr/lib64/python3.6/site-packages/matplotlib/cbook.py", line 416, in __call__ return mtd(*args, **kwargs) File "pop.py", line 51, in hover cont, ind = sc.contains(event) AttributeError: 'list' object has no attribute 'contains'