thank you for reading my question.
Assume that I have a polycyclic aromatic (let's call it "parent molecule") as shown below:
smile = "c1ccc2ocnc2c1"
mol = Chem.MolFromSmiles(smile)
When I draw sub-structures of the parent molecule, I notice that the bond angles in sub-structures are different from the bond angles in the parent molecule. Following is the code that I use:
from rdkit import Chem
from rdkit.Chem.Draw import rdMolDraw2D
from IPython.display import SVG
smile_1 = 'c(cc)cc'
smile_2 = 'n(co)c(c)c'
m1 = Chem.MolFromSmiles(smile_1,sanitize=False)
Chem.SanitizeMol(m1, sanitizeOps=(Chem.SanitizeFlags.SANITIZE_ALL^Chem.SanitizeFlags.SANITIZE_KEKULIZE^Chem.SanitizeFlags.SANITIZE_SETAROMATICITY))
m2 = Chem.MolFromSmiles(smile_2,sanitize=False)
Chem.SanitizeMol(m2, sanitizeOps=(Chem.SanitizeFlags.SANITIZE_ALL^Chem.SanitizeFlags.SANITIZE_KEKULIZE^Chem.SanitizeFlags.SANITIZE_SETAROMATICITY))
mols = [m1, m2]
smiles = ["smile_1", "smile_2"]
molsPerRow=2
subImgSize=(200, 200)
nRows = len(mols) // molsPerRow
if len(mols) % molsPerRow:
nRows += 1
fullSize = (molsPerRow * subImgSize[0], nRows * subImgSize[1])
d2d = rdMolDraw2D.MolDraw2DSVG(fullSize[0], fullSize[1], subImgSize[0], subImgSize[1])
d2d.drawOptions().prepareMolsBeforeDrawing=False
d2d.DrawMolecules(mols, legends=smiles)
d2d.FinishDrawing()
SVG(d2d.GetDrawingText())
Which results in the following drawing:
As can be seen, the angles between several bonds in sub-structures are different from the parent molecule.
Is there any way to draw sub-structures with the same bond angles as parent molecule?
Any help is greatly appreciated.
You can set the original positions of your parent to the substructure.
from rdkit import Chem
from rdkit.Chem.Draw import IPythonConsole
from rdkit.Chem import rdDepictor
rdDepictor.SetPreferCoordGen(True)
def getNiceSub(parent, sub):
# Get the coordinates of parent (also need to built a conformer)
mol = Chem.MolFromSmiles(parent)
rdDepictor.Compute2DCoords(mol)
# Get the coordinates of substructure to built a conformer
substruct = Chem.MolFromSmiles(sub, sanitize=False)
rdDepictor.Compute2DCoords(substruct)
# Get the index of the matched atoms
ms = mol.GetSubstructMatch(substruct)
# Get the positions of the matched atoms
conf1 = mol.GetConformer()
p = [list(conf1.GetAtomPosition(x)) for x in ms]
# Set the original positions of parent to substructure
conf2 = substruct.GetConformer()
for n in range(len(ms)):
conf2.SetAtomPosition(n, p[n])
return substruct
parent = 'c1ccc2ocnc2c1'
substructer = 'n(co)c(c)c'
nicesub = getNiceSub(parent, substructer)
parent
substructure
I'm trying to make a widget that demonstrates the relationship between a sine wave and it's phasor diagram. I want a pointer that follows the user's mouse movements but instead of freely moving around the page, I want it to stick to the waveform I've plotted and only follow the co-ordinates that make up that line. Kind of like a slider but along a sine wave! Any suggestions? Thanks. Here's what I've got so far;
import math
import Tkinter as tk
from Tkinter import PhotoImage, Canvas
from PIL import Image, ImageTk
sinwidget = tk.Tk()
main_canvas = tk.Canvas(sinwidget, width = 400, height = 400, bg= "white")
main_canvas.pack()
def callback(event):
canvas = event.widget
x = canvas.canvasx(event.x)
y = canvas.canvasy(event.y)
print canvas.find_closest(x, y)
draw(event.x, event.y)
def draw(x, y):
box.coords(pointer, x-20, y-20, x+20, y+20)
def exit_():
sinwidget.destroy()
box = main_canvas
box.bind('<Motion>', callback)
box.pack()
pointer = box.create_rectangle(0.2,0.2,0.2,0.2)
wavelength = 360
height = 400
center = height//2
degree = 1
increment = 0.0175
amplitude = -80
sin = []
for x in range(360):
sin.append(x * degree)
sin.append(int(math.sin(x * increment) * amplitude) + center)
sinwave = main_canvas.create_line(sin, fill="red", width=2.0)
xaxis = main_canvas.create_line(0, center, wavelength, center, fill="black",
width=3.0)
yaxis = main_canvas.create_line(2, 100, 2, 300, fill="black", width=3.0)
exit_button = tk.Button(sinwidget, text = "exit", command = exit_)
exit_button.pack()
sinwidget.mainloop()
Thanks for any help you can offer!
So using tkinter I have made a simple program that changes the color of all shapes on the canvas to a random color every second ,what I am looking for is a way to register every screen change and write down the time between screen changes in a separate file.I also need to do it without the help of too many external libraries if possible.
My code so far:
#!/usr/bin/python -W ignore::DeprecationWarning
import Tkinter
import tkMessageBox
import time
import random
colors = ['DarkOrchid1','chocolate3','gold2','khaki2','chartreuse2','deep pink','white','grey','orange']
top = Tkinter.Tk()
global b
b=0
C = Tkinter.Canvas(top, bg="blue", height=600, width=800)
bcg1=C.create_rectangle(0,0,800,100,fill=random.choice(colors))
bcg2=C.create_rectangle(0,100,800,200,fill=random.choice(colors))
bcg3=C.create_rectangle(0,200,800,300,fill=random.choice(colors))
bcg4=C.create_rectangle(0,300,800,400,fill=random.choice(colors))
bcg5=C.create_rectangle(0,400,800,500,fill=random.choice(colors))
bcg6=C.create_rectangle(0,500,800,600,fill=random.choice(colors))
bcgs=[bcg1,bcg2,bcg3,bcg4,bcg5,bcg6]
coord = 10, 50, 240, 210
rect1=C.create_rectangle(0,0,100,100,fill="green")
rect2=C.create_rectangle(700,500,800,600,fill="green")
rect3=C.create_rectangle(0,500,100,600,fill="green")
rect4=C.create_rectangle(700,0,800,100,fill="green")
def color():
global b
global bcgs
global color
if b==0:
C.itemconfig(rect1,fill='green')
C.itemconfig(rect2,fill='green')
C.itemconfig(rect3,fill='green')
C.itemconfig(rect4,fill='green')
b=1
count=0
for i in range(len(bcgs)):
C.itemconfig(bcgs[i],fill=random.choice(colors))
elif b==1:
C.itemconfig(rect1,fill='red')
C.itemconfig(rect2,fill='red')
C.itemconfig(rect3,fill='red')
C.itemconfig(rect4,fill='red')
b=0
for i in range(len(bcgs)):
C.itemconfig(bcgs[i],fill=random.choice(colors))
top.after(2000, color)
C.pack()
color()
top.mainloop()
Unless you use a real time OS, you will never get perfect timing. You can bank on being a few milliseconds off the mark. To see how much, you can calculate the difference in time.time(). For the best accuracy, move the after call to the first thing in the function.
That plus some other improvements:
#!/usr/bin/python -W ignore::DeprecationWarning
import Tkinter
import time
import random
from itertools import cycle
colors = ['DarkOrchid1','chocolate3','gold2','khaki2','chartreuse2','deep pink','white','grey','orange']
rect_colors = cycle(['green', 'red'])
top = Tkinter.Tk()
C = Tkinter.Canvas(top, bg="blue", height=600, width=800)
bcg1=C.create_rectangle(0,0,800,100,fill=random.choice(colors))
bcg2=C.create_rectangle(0,100,800,200,fill=random.choice(colors))
bcg3=C.create_rectangle(0,200,800,300,fill=random.choice(colors))
bcg4=C.create_rectangle(0,300,800,400,fill=random.choice(colors))
bcg5=C.create_rectangle(0,400,800,500,fill=random.choice(colors))
bcg6=C.create_rectangle(0,500,800,600,fill=random.choice(colors))
bcgs=[bcg1,bcg2,bcg3,bcg4,bcg5,bcg6]
coord = 10, 50, 240, 210
rect1=C.create_rectangle(0,0,100,100,fill="green")
rect2=C.create_rectangle(700,500,800,600,fill="green")
rect3=C.create_rectangle(0,500,100,600,fill="green")
rect4=C.create_rectangle(700,0,800,100,fill="green")
rects = [rect1,rect2,rect3,rect4]
last_time = time.time()
def color():
top.after(2000, color)
global last_time
rect_color = next(rect_colors)
for item in rects:
C.itemconfig(item, fill=rect_color)
for item in bcgs:
C.itemconfig(item, fill=random.choice(colors))
print("{} seconds since the last run".format(time.time() - last_time))
last_time = time.time()
C.pack()
color()
top.mainloop()
I have made a horizontal bar graph, now I need to add markers on the bars. How can I do so?
The code I have so far is shown below:
def plot_comparison():
lengths = [11380, 44547, 166616, 184373, 193068, 258004, 369582, 462795, 503099, 581158, 660724, 671812, 918449]
y_pos = np.arange(len(length))
error = np.random.rand(len(length))
plt.barh(y_pos, length, xerr=error, align='center', alpha=0.4)
plt.yticks(y_pos, length)
plt.xlabel('Lengths')
plt.title('Comparison of different cuts')
plt.show()
You can simply add a plot command, plotting the y_pos against the lengths. Make sure to specify a maker and set linestyle to "" (or "none") otherwise the markers will be connected by straight lines.
The following code may be what you're after.
import matplotlib.pyplot as plt
import numpy as np
lengths = [11380, 44547, 166616, 184373, 193068, 258004, 369582, 462795, 503099, 581158, 660724, 671812, 918449]
y_pos = np.arange(len(lengths))
error = np.array(lengths)*0.08
plt.barh(y_pos, lengths, xerr=error, align='center', alpha=0.4)
plt.plot(lengths, y_pos, marker="D", linestyle="", alpha=0.8, color="r")
plt.yticks(y_pos, lengths)
plt.xlabel('Lengths')
plt.title('Comparison of different cuts')
plt.show()
I wanted to use the matplotlib slider as seen in an example from a previous question (below) inside a GUI window (such as TkInter etc). But, in a non-global context, the variables for the plot ("spos, fig, ax") are not defined. My understanding is that because update is used as a callback function, one can't or shouldn't pass arguments.
If so, how can a plot be updated without global variables? or
How can I obtain the slider position outside the callback function?
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
fig, ax = plt.subplots()
plt.subplots_adjust(bottom=0.25)
t = np.arange(0.0, 100.0, 0.1)
s = np.sin(2*np.pi*t)
l, = plt.plot(t,s)
plt.axis([0, 10, -1, 1])
axcolor = 'lightgoldenrodyellow'
axpos = plt.axes([0.2, 0.1, 0.65, 0.03], axisbg=axcolor)
spos = Slider(axpos, 'Pos', 0.1, 90.0)
def update(val):
pos = spos.val
ax.axis([pos,pos+10,-1,1])
fig.canvas.draw_idle()
spos.on_changed(update)
plt.show()
Related:
1) Another related question seems to cover this topic but does not seem to address how the position of the slider is obtained.
2) A similar question was asked and solved with Slider.set_val(). It seems in my case I would need Slider.get_val() instead.
It is possible to pass more arguments to the callback function, for example with functools.partial
def update(data, val):
pos = spos.val
ax.axis([pos,pos+10,-1,1])
fig.canvas.draw_idle()
data['position'] = pos
import functools
data = dict()
spos.on_changed(functools.partial(update, data))
plt.show()
try:
print data['position']
except KeyError:
pass
A class with __call__ method could also be used as a callback.