def scale_mpl(min_value, max_value): """Matplotlib axis ticks""" from matplotlib.figure import Figure ax = Figure().add_subplot(111) ax.plot([min_value, max_value], [min_value, max_value]) #from matplotlib import pyplot as plt #plt.plot([min_value, max_value],[min_value, max_value]) #print(plt.gca().get_xticks()) ticks = list(ax.get_xticks()) xlim = ax.get_xlim() if ticks[0] < xlim[0]: del ticks[0] if ticks[-1] < xlim[1]: del ticks[-1] s = {} s['ticks'] = list(ticks) s['tick_spacing'] = ticks[1] - ticks[0] s['tick_min'] = ticks[0] s['tick_max'] = ticks[-1] s['num_ticks'] = len(ticks) s['min_value'] = min_value s['max_value'] = max_value return s
def polar_plot(self, canvas: FigureCanvasTkAgg, ax: Figure) -> None: c = ['r', 'b', 'g'] # plot marker colors ax.clear() # clear axes from previous plot for i in range(3): # plots 3 random data sets theta = np.random.uniform(0, 360, 10) r = np.random.uniform(0, 1, 10) ax.plot(theta, r, linestyle="None", marker='o', color=c[i]) canvas.draw()
def plot(self): df = pd.read_csv('CSVs/' + self.ASIN + ".csv") # set axis x = df["Date"] y = df["Price"] # Plot Data plt = Figure(figsize=(7, 4)) plt.plot(x, y) # Add Labels plt.title("\n".join(wrap(name, 40)), fontsize=18) plt.xlabel('Date', fontsize=14) plt.xticks(rotation=90, fontsize=8) plt.ylabel('Price ($)', fontsize=14)
def ATMPlot(ATM): # plt.figure(figsize=(20, 5)) X = ATM.inputs["X"] targets = ATM.inputs["y"] numcols = ATM.inputs.shape[0] for i, col in enumerate(X.columns): fig = Figure() fig.subplot(1, numcols, i + 1) x = X[col] y = targets fig.plot(x, y, 'o') # Create regression line fig.plot(np.unique(x), np.poly1d(np.polyfit(x, y, 1))(np.unique(x))) fig.title(col) fig.xlabel(col) fig.ylabel(ATM.props["target"]) ATM.reportPlot(fig) ATM.output(ATM.inputs)
class Application: def __init__(self, master): self.master = master self.builder = builder = pygubu.Builder() builder.add_from_file(UI_FILE) self.mainwindow = builder.get_object('main_frame', master) self.text = builder.get_object('text_1') self.browse = builder.get_object('btn_browse') self.seq_bin = "" self.V_sortie = [] self.abscisse = [] self.msg_err = "" self.longueur = 0 self.c1 = Figure() self.c2 = Figure() self.cb_Volt = builder.get_object('cb_Volt') self.cb_Res = builder.get_object('cb_Res') self.V_ref = 10 self.R = 5 self.top3 = tk.Toplevel self.canvas1 = canvas1 = builder.get_object('canvas_1') self.canvas2 = canvas2 = builder.get_object('canvas_2') # Setup matplotlib canvas self.figure1 = fig1 = Figure(figsize=(4, 2), dpi=100) self.can1 = can1 = FigureCanvasTkAgg(fig1, master=canvas1) can1.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) # Setup matplotlib toolbar (optional) self.toolbar1 = NavigationToolbar2Tk(can1, canvas1) self.toolbar1.update() can1._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) # Setup matplotlib canvas2 self.figure = fig = Figure(figsize=(4, 1.5), dpi=100) self.canvas = canvas = FigureCanvasTkAgg(fig, master=canvas2) canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) # Setup matplotlib toolbar (optional) 2 self.toolbar = NavigationToolbar2Tk(canvas, canvas2) self.toolbar.update() canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1) self.reset() self.cb_Volt.current(0) self.cb_Res.current(0) builder.connect_callbacks(self) def about_window(self): frame3 = tk.Frame try: self.quit_about() except: "" builder2 = pygubu.Builder() builder2.add_from_file('interface.ui') self.top3 = tk.Toplevel(self.mainwindow) frame3 = builder2.get_object('frame_abt', self.top3) img_label = builder2.get_object("label_img") img_label.new_image = tk.PhotoImage(file="imgs/hhh1.png") img_label.config(image=img_label.new_image) self.top3.iconphoto(True, self.icon) callbacks = {} builder2.connect_callbacks(self) def quit_about(self): self.top3.destroy() def reset(self): self.can1.get_tk_widget().forget() self.canvas.get_tk_widget().forget() self.toolbar1.forget() self.toolbar.forget() self.canvas1 = canvas1 = self.builder.get_object('canvas_1') self.canvas2 = canvas2 = self.builder.get_object('canvas_2') # Setup matplotlib canvas self.figure1 = fig1 = Figure(figsize=(5, 2), dpi=100) self.can1 = can1 = FigureCanvasTkAgg(fig1, master=canvas1) can1.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) self.toolbar1 = NavigationToolbar2Tk(can1, canvas1) self.toolbar1.update() # Setup matplotlib canvas2 self.figure = fig = Figure(figsize=(5, 2), dpi=100) self.canvas = canvas = FigureCanvasTkAgg(fig, master=canvas2) canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) self.toolbar = NavigationToolbar2Tk(canvas, canvas2) self.toolbar.update() self.figure.subplots_adjust(top=0.886, right=0.976, bottom=0.22, left=0.129) self.figure1.subplots_adjust(top=0.886, right=0.976, bottom=0.22, left=0.129) self.c1 = self.figure.add_subplot(111) self.c2 = self.figure1.add_subplot(111) self.c1.set_ylabel("Tension (V)") self.c1.set_xlabel("Instant t") self.c1.set_title("Représentation du signal Analogique") self.c2.set_ylabel("Symbole binaire") self.c2.set_xlabel("Instant t") self.c2.set_title("Représentation du signal Numérique") #self.V_sortie=[] #self.can1.draw() def plot(self): try: verified = self.cna() if verified: #######courbe binaire bin = [int(self.seq_bin[i]) for i in range(self.longueur)] x_bin = [i for i in range(0, self.longueur * 10, 10)] self.c2.step(x_bin, bin) ########courbe analogique x_new = np.linspace(1, int(self.longueur / 4), 300) a_BSpline = interpolate.make_interp_spline( self.abscisse, self.V_sortie) V_s = a_BSpline(x_new) self.c1.plot(x_new, V_s) self.canvas.draw() self.can1.draw() else: #rise error print("error" + str(verified) + str()) self.rise_err() except Exception as e: tk.messagebox.showerror( title="Erreur", message="Erreur inconnue, L'application va se fermer \n" + str(e)) self.btn_exit() def rise_err(self): tk.messagebox.showerror(title="Erreur", message=self.msg_err) def get_V_R(self): v_mv = str(self.builder.get_object("cb_Volt").get()) r_mr = str(self.builder.get_object("cb_Res").get()) tmpV = self.builder.get_object("tb_Volt").get() tmpR = self.builder.get_object("tb_Res").get() tmpV = tmpV.rstrip("\n") tmpV = tmpV.replace(",", ".") tmpR = tmpR.rstrip("\n") tmpR = tmpR.replace(",", ".") try: if v_mv == "V": self.V_ref = float(tmpV) else: self.V_ref = float(tmpV) * 0.001 if r_mr == "Ω": self.R = float(tmpR) else: self.R = float(tmpR) * 0.001 except: tk.messagebox.showerror( title="Erreur", message="Erreur d'entrée dans les champs V_ref et R") self.V_ref = 10 self.R = 5 def cna(self): self.seq_bin = self.text.get("1.0", tk.END) self.seq_bin = self.seq_bin.rstrip("\n") verified = self.verif_seq_bin() if verified: self.longueur = len(self.seq_bin) print(self.longueur) self.abscisse = [ i + 1 for i in range(0, int(len(self.seq_bin) / 2), 2) ] self.V_sortie = [] #self.V_ref =V_ref= 10 # 10V #self.R = R = 5 # 5 ohm V_ref = self.V_ref R = self.R print(str(V_ref) + " " + str(R)) for k in range(int(self.longueur / 4)): indice = k * 4 i3 = (V_ref * int(self.seq_bin[indice])) / (4 * R) i2 = (V_ref * int(self.seq_bin[indice + 1])) / (8 * R) i1 = (V_ref * int(self.seq_bin[indice + 2])) / (16 * R) i0 = (V_ref * int(self.seq_bin[indice + 3])) / (32 * R) self.V_sortie.append(2 * R * (i3 + i2 + i1 + i0)) return verified def browse_nd_read(self): file = tk.filedialog.askopenfile(mode="r", filetypes=[('', '.txt')]) if (file is not None): print(type(file)) self.seqbin = file.read() self.text.config(state=tk.NORMAL) self.text.delete(1.0, tk.END) self.text.insert("end", self.seqbin) self.text.config(state=tk.DISABLED) def verif_seq_bin(self): verified = True self.msg_err = "" if len(self.seq_bin) < 16: verified = False print("<16 : " + str(len(self.seq_bin))) self.msg_err = "Longueur de la sequence binaire est inferieur à 16 (" + str( len(self.seq_bin)) + ") " #if not self.seq_bin.isnumeric(): # verified=False #else: else: for x in self.seq_bin: if x not in {'0', '1'}: verified = False print("not 0 or 1") #debugging self.msg_err = "La sequence contient des valeurs autres que 0 et 1" break if verified: if len(self.seq_bin) % 4 != 0: print(str(len(self.seq_bin) % 4)) for i in range(4 - (len(self.seq_bin) % 4)): self.seq_bin = self.seq_bin + "0" print(self.seq_bin) return verified def browse_enabler(self, radio): if (radio == "rad_browse"): self.text.delete(1.0, tk.END) self.text.config(state=tk.DISABLED) self.browse.config(state=tk.NORMAL) else: self.text.config(state=tk.NORMAL) self.text.delete(1.0, tk.END) self.browse.config(state=tk.DISABLED) def btn_exit(self): #self.can1.get_tk_widget().forget() #self.canvas.get_tk_widget().forget() self.master.quit()
class BasicGrapher(grapher.BasicGrapher): """Documentation string for Basic Grapher A simple graphing widget By Randy P. and Bart O.""" def __init__(self, parent=None, **kw): self.ax = Figure(figsize=(4.3, 3.0)).gca() self.ax2d = self.ax self.ax3d = None if kw.get("hide"): self.canvas = FigureCanvasAgg(self.ax.get_figure()) else: self.canvas = FigureCanvasTkAggRedraw(self, parent) tk_widget = self.canvas.get_tk_widget() self.quit = tk_widget.quit self.bind = tk_widget.bind self.unbind = tk_widget.unbind self.winfo_rootx = tk_widget.winfo_rootx self.winfo_rooty = tk_widget.winfo_rooty self.ax.set_autoscale_on(0) self.postscript = self.canvas.print_figure self.savefig = self.ax.get_figure().savefig self.redrawlabels = 0 callback = self.__optionCallback grapher.BasicGrapher.__init__(self, parent, callback, **kw) optionDefaults = {} optionDefaults["xticks"] = (None, callback) optionDefaults["yticks"] = (None, callback) optionDefaults["zticks"] = (None, callback) optionDefaults["background"] = ("white", callback) optionAliases = {} optionAliases["bg"] = "background" self.addOptions(**optionDefaults) self.addAliases(**optionAliases) for key in [ "grid", "decorations", "xlabel", "ylabel", "zlabel", "xlabel_fontsize", "ylabel_fontsize", "zlabel_fontsize", "minx", "maxx", "miny", "maxy", "minz", "maxz", "width", "height", "left_margin", "right_margin", "top_margin", "bottom_margin" ]: self.__optionCallback(key, self.cget(key), []) matplotlib.rcParams["axes.edgecolor"] = self.cget("foreground") def pack(self, **kw): self.canvas.get_tk_widget().pack(kw) def update(self): if isinstance(self.canvas, FigureCanvasTkAggRedraw): self.canvas.get_tk_widget().update() FigureCanvasTkAgg.draw(self.canvas) else: self.canvas.draw() def __optionCallback(self, key, value, options): if key in [ "minx", "maxx", "miny", "maxy", "minz", "maxz", "realwidth", "realheight", "azimuth", "elevation", "left_margin", "right_margin", "top_margin", "bottom_margin" ]: self.redrawlabels = 1 if key[:3] in ["min", "max"]: minc = self.cget("min" + key[3]) maxc = self.cget("max" + key[3]) if minc < maxc: func = None if self.ax is self.ax3d: func = getattr(self.ax, "set_" + key[3] + "lim3d") self._cur_lims = (Axes.get_xlim(self.ax), Axes.get_ylim(self.ax)) elif key[3] != 'z': func = getattr(self.ax, "set_" + key[3] + "lim") if func is not None: func(minc, maxc) tickskey = key[3] + "ticks" ticksval = self.cget(tickskey) if ticksval is not None: self.__optionCallback(tickskey, ticksval, options) elif key == "realwidth": lm = float(self.cget("left_margin")) rm = float(self.cget("right_margin")) self.ax.get_figure().subplots_adjust(left=lm / value, right=1 - rm / value) elif key == "realheight": tm = float(self.cget("top_margin")) bm = float(self.cget("bottom_margin")) top = 1 - tm / value bottom = bm / value if top > bottom: self.ax.get_figure().subplots_adjust(top=top, bottom=bottom) elif key == "left_margin": fig = self.ax.get_figure() width = fig.get_figwidth() * fig.get_dpi() fig.subplots_adjust(left=value / width) elif key == "right_margin": fig = self.ax.get_figure() width = fig.get_figwidth() * fig.get_dpi() fig.subplots_adjust(right=1 - value / width) elif key == "top_margin": fig = self.ax.get_figure() height = fig.get_figheight() * fig.get_dpi() fig.subplots_adjust(top=1 - value / height) elif key == "bottom_margin": fig = self.ax.get_figure() height = fig.get_figheight() * fig.get_dpi() fig.subplots_adjust(bottom=value / height) elif self.ax is self.ax3d: elev = self.cget("elevation") azim = self.cget("azimuth") if elev is not None or azim is not None: self.ax.view_init(elev, azim) elif key == "grid": if value in ["yes", True]: self.ax.grid(color=self.cget("foreground")) else: self.ax.grid(False) elif key in ["width", "height"]: if isinstance(self.canvas, FigureCanvasTkAggRedraw): self.canvas.get_tk_widget()[key] = value else: fig = self.ax.get_figure() if key == "width": fig.set_figwidth(float(value) / fig.get_dpi()) self._configNoDraw(realwidth=value) else: fig.set_figheight(float(value) / fig.get_dpi()) self._configNoDraw(realheight=value) elif key == "top_title": fontsize = self.cget("top_title_fontsize") if fontsize is None: self.ax.set_title(value) else: self.ax.set_title(value, fontsize=fontsize) elif key == "top_title_fontsize": title = self.cget("top_title") if title is not None: self.ax.set_title(title, fontsize=value) elif key in ["background", "bg"]: if hasattr(self.ax, 'set_facecolor'): # matplotlib >= 2.0 self.ax.set_facecolor(value) else: self.ax.set_axis_bgcolor(value) elif key in ["foreground", "fg"]: matplotlib.rcParams["axes.edgecolor"] = self.cget("foreground") self.redrawlabels = 1 if self.cget("grid") in ["yes", True]: self.ax.grid(color=value) elif key == "color_list": color_list = value.split() i = 0 for d in self.data: if d["newsect"] is None or d["newsect"]: i = i + 1 if d["color"] is None: color = i else: color = d["color"] d["mpline"].set_color(color_list[color % len(color_list)]) elif key == "decorations": if value: self.ax.set_axis_on() else: self.ax.set_axis_off() elif key == "use_symbols": self.plotsymbols() elif key == "use_labels": self.plotlabels() elif key in ["xlabel", "ylabel", "zlabel"]: if value is None: value = "" fontsize = self.cget(key + "_fontsize") if hasattr(self.ax, "set_" + key): func = getattr(self.ax, "set_" + key) if fontsize is None: func(value) else: func(value, fontsize=fontsize) elif key in ["xlabel_fontsize", "ylabel_fontsize", "zlabel_fontsize"]: label = self.cget(key[:6]) if hasattr(self.ax, "set_" + key[:6]): func = getattr(self.ax, "set_" + key[:6]) if value is None: func(label) else: func(label, fontsize=value) elif key in ["xticks", "yticks", "zticks"]: if value is None: if self.ax is self.ax3d: axis = getattr(self.ax, "w_" + key[0] + "axis") axis.set_major_locator(AutoLocator()) elif key == "xticks": self.ax.set_xscale('linear') else: self.ax.set_yscale('linear') else: min = self.cget("min" + key[0]) max = self.cget("max" + key[0]) ticks = [ min + ((max - min) * i) / float(value - 1) for i in range(value) ] if self.ax is self.ax3d: axis = getattr(self.ax, "w_" + key[0] + "axis") axis.set_major_locator(FixedLocator(ticks)) elif key == "xticks": self.ax.set_xticks(ticks) elif key == "yticks": self.ax.set_yticks(ticks) def _delAllData(self): for d in self.data: if "mpline" in d: self.ax.lines.remove(d["mpline"]) self.data = [] # set type for next data try: zcolumn = self.cget(self.cget("type") + "_z") except Tkinter.TclError: #in regression test return oldax = self.ax if zcolumn is None or Axes3D is None: if zcolumn is not None: self._configNoDraw({self.cget("type") + "_z": None}) print("\nmatplotlib 0.98.x does not support 3D plots.") print("Plotting only the first two coordinates.") if self.ax is self.ax3d: # restore zoom mode new_zoom_mode = self.zoom_mode self.ax = self.ax2d else: if self.ax3d is None: self.ax3d = Axes3D(self.ax.get_figure()) try: self.ax3d.set_autoscale_on(0) except TypeError: #Matplotlib 1.1 bug self.ax2d.set_autoscale_on(0) self.ax3d.set_autoscalez_on(0) if self.ax is self.ax2d: # remember zoom mode and disable zoom if isinstance(self.canvas, FigureCanvasTkAggRedraw): self.zoom_mode = self.toolbar.mode new_zoom_mode = '' self.ax = self.ax3d if self.ax is not oldax: if (isinstance(self.canvas, FigureCanvasTkAggRedraw) and new_zoom_mode != self.toolbar.mode): if "rect" in new_zoom_mode: self.toolbar.zoom() elif "pan" in new_zoom_mode: self.toolbar.pan() elif "rect" in self.toolbar.mode: self.toolbar.zoom() elif "pan" in self.toolbar.mode: self.toolbar.pan() #copy settings from 3d to 2d or vice versa for key in ("grid", "decorations", "xlabel", "ylabel", "zlabel", "xticks", "yticks", "zticks", "minx", "maxx", "miny", "maxy", "minz", "maxz", "azimuth", "elevation", "top_title", "background"): self.__optionCallback(key, self.cget(key), []) def _delData(self, index): if "mpline" in data[index]: self.ax.lines.remove(data[index]["mpline"]) del self.data[index] def clear(self): if len(self.ax.get_figure().axes) > 0: self.ax.get_figure().delaxes(self.ax.get_figure().axes[0]) def draw(self): if self.redrawlabels: self.plotlabels() if len(self.ax.get_figure().axes) == 0: self.ax.get_figure().add_axes(self.ax) if isinstance(self.canvas, FigureCanvasTkAggRedraw): FigureCanvasTkAgg.draw(self.canvas) else: self.canvas.draw() def plot(self): color_list = self.cget("color_list").split() # data line_width = self.cget("line_width") dashes = list(map(float, self.cget("dashes"))) i = -1 for d in self.data: if d["newsect"] is None or d["newsect"]: i = i + 1 curve = "curve:%d" % (i, ) if self.ax is self.ax2d: v = [d["x"], d["y"]] else: v = [d["x"], d["y"], d["z"]] if d["color"] is None: color = i else: color = d["color"] kw = {'color': color_list[color % len(color_list)]} if len(v[0]) == 1: # If we only have one point we draw a small circle or a pixel if self.cget("type") == "solution": marker = 'o' else: marker = ',' v.append(marker) #tags=("data_point:%d"%(0,),curve,"data") else: stable = d["stable"] #tags=(curve,"data") kw['lw'] = line_width if stable is not None and not stable: kw.update({'ls': '--', 'dashes': dashes}) if self.ax is self.ax2d: self.ax.plot(*v, **kw) else: self.ax.plot3D(*v, **kw) d["mpline"] = self.ax.lines[-1] if len(self.ax.get_figure().axes) == 0: self.ax.get_figure().add_axes(self.ax) def __setitem__(self, key, value): self.configure(**{key: value}) def __getitem__(self, key): return self.cget(key)
def plot_things(x, y): fig = Figure(figsize=(5.5, 5.15)) fig.plot(x, y) canv = FigureCanvasTkAgg(fig, master=root) canv.get_tk_widget().grid(row=0, column=0, columnspan=1) canv.draw()
class PlotCanvas(FigureCanvas): """ A Widget view that presents a plot or image """ current_figure = None axes = None def __init__(self, parent=None, width=10, height=10, dpi=100): self.current_figure = Figure(figsize=(width, height), dpi=dpi) self.axes = self.current_figure.add_subplot(111) FigureCanvas.__init__(self, self.current_figure) self.current_figure.patch.set_facecolor("none") self.setStyleSheet("background-color:rgba(0, 0, 0, 0)") self.setParent(parent) FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding) FigureCanvas.updateGeometry(self) def plot_graph(self, x_axis, y_axis, title=""): """ Plots a graph in the view :param x_axis: The x-axis to display :type x_axis: Numpy array :param y_axis: The y-axis to display :type y_axis: Numpy array :param title: The title to display :type title: str """ self.clear_figure() self.current_figure = self.figure.add_subplot(111) self.current_figure.plot(x_axis, y_axis) self.current_figure.set_title(title) self.draw() def plot_image(self, image, title=""): """ Displays a image in a view :param image: The image to display :type image: Numpy array :param title: The title to display :type title: str """ self.clear_figure() self.current_figure = self.figure.add_subplot(111) self.current_figure.axis("off") if image.ndim == 2: self.current_figure.imshow(image, plt.cm.gray) else: self.current_figure.imshow(image) self.current_figure.set_title(title) self.draw() def clear_figure(self): """ Clears the current figure """ if self.current_figure is not None: plt.close(111) self.current_figure = None
def SMA(select): ticker = SP500.get(select) try: url_prefix = 'https://sandbox.iexapis.com/stable/stock/' url_suffix = '/chart/max?token=Tsk_d536dffef19e4ae4941ea4ac530d6133' full_url = '{}{}{}'.format(url_prefix, ticker.lower(), url_suffix) source = requests.get(full_url, timeout=20) soup = BeautifulSoup(source.text, 'html.parser') data = json.loads(str(soup)) except (requests.exceptions.Timeout, requests.exceptions.ConnectionError): return ['error', 'Error: Internet connection failure.'] except (ValueError, requests.exceptions.HTTPError): return ['error', 'Error: {}'.format(full_url) + '\ndoes not exist.'] except: return [ 'error', 'Error parsing IEX API. Please contact the creator for its resolution.' ] if not data: error_msg = 'Error: IEX API cannot load price data for {}.'.format( select) return ['error', error_msg] data = pd.DataFrame(data, columns=['date', 'close']) data.rename(columns={'date': 'Date', 'close': select}, inplace=True) data = data.set_index('Date') SMAs_Short = 50 SMAs_Long = 250 df = Figure() df = data df['SMAs_Short'] = df[select].rolling(SMAs_Short).mean() df['SMAs_Long'] = df[select].rolling(SMAs_Long).mean() df.dropna(inplace=True) df.plot(figsize=(10, 10), linewidth=0.8) plt.ylabel('Price') plt.legend(fontsize='large') df['Position'] = np.where(df['SMAs_Short'] > df['SMAs_Long'], 1, -1) df['Trade'] = np.where(df['Position'] != df['Position'].shift(1), 'Trade', 'Still') ax = df.plot(secondary_y='Position', figsize=(10, 10), linewidth=0.8) plt.ylabel('Position') plt.title('SMAs Trading Strategy: ' + select) df = df[df['Trade'] == 'Trade'].drop(['SMAs_Short', 'SMAs_Long', 'Trade'], axis=1) res = [] for i in range(len(df)): if df['Position'][i] == 1: res.append('Buy {} on {} Price at {}\n'.format( ticker, str(df.index[i]), str(format(df[select][i], ',')))) else: res.append('Sell {} on {} Price at {}\n'.format( ticker, str(df.index[i]), str(format(df[select][i], ',')))) dir = '{}{}'.format(os.environ["HOME"], '/smagraph.png') plt.savefig(dir) image = Image.open(dir) width, height = image.size left = width / 17 top = height / 17 right = width bottom = height image = image.crop((left, top, right, bottom)) image.rotate(270).save(dir) return [ dir, 'Simple Moving Averages Trading Strategy for {} (Ticker: {}).{}{}'. format(str(select), ticker, '\n' * 2, str(''.join(res))) ]