Save an animation at the final step as a figure - python-2.7

I wrote a script which animates the results I obtained, using matplotlib.
Besides the animation I got, I wanted to save the figure at the final step of the animation; just before the animation is repeated. I defined a save-flag, to avoid the figure being saved over and over. You can see the simplified version of my code below:
#!/usr/bin/env python
import numpy as np
from matplotlib import pyplot as plt
import matplotlib.animation as animation
x = np.array(range(12))
y = np.array([i**2 for i in range(12)])
fig = plt.figure()
ax = plt.axes(xlim = (0,15), ylim = (0,150))
line, = ax.plot([],[], 'o-')
def init():
line.set_data([], [])
return line,
save_flag = False
def animate(i):
i = (i+1)%(len(x)+1)
line.set_data(x[0:i], y[0:i])
global save_flag
if (save_flag == False) and (i == (len(x)-1)):
print "\nThe figure is being saved!\n"
fig.savefig("foo" + ".png")
save_flag = True
return line,
ani = animation.FuncAnimation(fig, animate, repeat=True, blit=True, init_func=init)
plt.show()
If you run the script, you will probably see that, at the end of the first loop, the the animation becomes erroneous. This error is due to the blit, which is set True. However, if it is set to False, then the figure repeats itself as it should be.
Why is there such a problem; could it be a bug? (My Python version is 2.7.5+.)
Is there a better way to save a figure at the end of an animation?

Related

Code is Not able to find my function in Python(Spark) class

I need some help regarding the error in code. My Code consists of retrieving the zomato reviews and storing it in HDFS and again reading it performing Recommender Analtyics on it. I am getting a problem regarding my function is not recognizing in pyspark code. I am not entirely pasting the code as it might be confusing so i am writing a small similar use case for your easy understanding.
I am trying to read a file from local and converting it to dataframe from rdd and performing some operations and again converting it to rdd and performing map operation to have delimiter by '|' and then save it to HDFS.
When i try to call self.filter_data(y) in lambda func of check function its not recognizing and giving me error as
Exception: It appears that you are attempting to reference
SparkContext from a broadcast variable, action, or transformation.
SparkContext can only be used on the driver, not in code that it run
on workers. For more information, see SPARK-5063.
****CAN ANY ONE HELP ME WHY MY FILTER_DATA FUNCTION IS NOT RECOGNISING? SHOULD I NEED TO ADD ANY THING OR ANY THING WRONG IN THE WAY I AM CALLING. PLEASE HELP ME. THANKS IN ADVANCE****
INPUT VALUE
starting
0|0|ffae4f|0|https://b.zmtcdn.com/data/user_profile_pictures/565/aed32fa2eb18bb4a5a3ba426870fd565.jpg?fit=around%7C100%3A100&crop=100%3A100%3B%2A%2C%2A|https://www.zomato.com/akellaram87?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1|2.5|FFBA00|Well...|unknown|16946626|2017-08-01T00-25-43.455182Z|30059877|Have been here for a quick bite for lunch, ambience and everything looked good, food was okay but presentation was not very appealing. We or...|2017-04-15 16:38:38|Big Foodie|6|Venkata Ram Akella|akellaram87|Bad Food|0.969352505662|0|0|0|0|0|0|1|1|0|0|1|0|0|0.782388212399
ending
starting
1|0|ffae4f|0|https://b.zmtcdn.com/data/user_profile_pictures/4d1/d70d7a57e1bfdf296ff4db3d8daf94d1.jpg?fit=around%7C100%3A100&crop=100%3A100%3B%2A%2C%2A|https://www.zomato.com/users/sm4-2011696?utm_source=api_basic_user&utm_medium=api&utm_campaign=v2.1|1|CB202D|Avoid!|unknown|16946626|2017-08-01T00-25-43.455182Z|29123338|Giving a 1.0 rating because one cannot proceed with writing a review, without rating it. This restaurant deserves a 0 star rating. The qual...|2017-01-04 10:54:53|Big Foodie|4|Sm4|unknown|Bad Service|0.964402034541|0|1|0|0|0|0|0|1|0|0|0|1|0|0.814540622345
ending
My code:
if __name__== '__main__':
import os,logging,sys,time,pandas,json;from subprocess
import PIPE,Popen,call;from datetime import datetime, time, timedelta
from pyspark import SparkContext, SparkConf
conf = SparkConf().setAppName('test')
sc = SparkContext(conf = conf,pyFiles=['/bdaas/exe/nlu_project/spark_classifier.py','/bdaas/exe/spark_zomato/other_files/spark_zipcode.py','/bdaas/exe/spark_zomato/other_files/spark_zomato.py','/bdaas/exe/spark_zomato/conf_files/spark_conf.py','/bdaas/exe/spark_zomato/conf_files/date_comparision.py'])
from pyspark.sql import Row, SQLContext,HiveContext
from pyspark.sql.functions import lit
sqlContext = HiveContext(sc)
import sys,logging,pandas as pd
import spark_conf
n = new()
n.check()
class new:
def __init__(self):
print 'entered into init'
def check(self):
data = sc.textFile('file:///bdaas/src/spark_dependencies/classifier_data/final_Output.txt').map(lambda x: x.split('|')).map(lambda z: Row(restaurant_id=z[0], rating = z[1], review_id = z[2],review_text = z[3],rating_color = z[4],rating_time_friendly=z[5],rating_text=z[6],time_stamp=z[7],likes=z[8],comment_count =z[9],user_name = z[10],user_zomatohandle=z[11],user_foodie_level = z[12],user_level_num=z[13],foodie_color=z[14],profile_url=z[15],profile_image=z[16],retrieved_time=z[17]))
data_r = sqlContext.createDataFrame(data)
data_r.show()
d = data_r.rdd.collect()
print d
data_r.rdd.map(lambda x: list(x)).map(lambda y: self.filter_data(y)).collect()
print data_r
def filter_data(self,y):
s = str()
for i in y:
print i.encode('utf-8')
if i != '':
s = s + i.encode('utf-8') + '|'
print s[0:-1]
return s[0:-1]

Can't remove matplotlib's padding around imshow() figure

I'm embedding matplotlib into my PyQt4 GUI and I'm having a heck of a time. I can get the image to display but it adds a very thick padding around the content that I'd like to remove. Here's what I'm doing:
from PyQt4.QtCore import *
from PyQt.QtGui import *
import numpy as np
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4Agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.image as mpImage
import matplotlib.pyplot as plt
class MatPlotLibImage(FigureCanvas):
def __init__(self):
super(MatPlotLibImage, self).__init__(self.fig)
self.axes = self.fig.add_subplot(111)
def LoadImage():
image = mpImage.imread("myImage.png")
imgplot = self.axes.imshow(image, interpolation="nearest")
# plt.axis("Off") -> Doesn't do anything as far as I can tell
imgplot.axes.set_axis_off() # Gets rid of frame
imgplot.axes.get_xaxis().set_visible(False) # Turn off x-axis
imgplot.axes.get_yaxis().set_visible(False) # Turn off y-axis
If I add this widget to a QDockWidget I get the following result:
As you can see it renders with a large white padding around the content. I cannot seem to remove this and everything I'm turning up online is focused on removing the padding when saving the image, not displaying. Does anyone know how to remove this padding at display time? Thanks in advance.
You may use subplots_adjust to get rid of the margins. I.e.
self.fig.subplots_adjust(bottom=0, top=1, left=0, right=1)
This will tell the figure not to use any margins around its child axes. You may then still get some white space to one direction, which is due to the canvas aspect ratio not being the same as the image aspect. However, I think that you don't want to change the image aspect and so this remaining margin would acutally be desired.

Graphing in Tkinter frame, updating info in Tkinter

So I am currently working on a basic stock program, and I have been able to get my graphs (of stock data from the last month) on my tkinter window any tips on how to actively update my tkinter window would be great! (FYI I am very new to programming, this is my first year, so please try to explain in basic terms!) Heres my code:
import numpy as np
import datetime as dt
import yahoo_finance as yf
import matplotlib.pyplot as plt
from Tkinter import *
import quandl
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
root=Tk()
root.geometry('1400x875')
root.title("Stock Information")
fmain=Frame(root, width=1400, height=900, bg='orange',bd=5)
fmain.place(x=100, y=0)
today=dt.date.today()
thirty_day_graph_frame=Frame(fmain, width=645, height=400,bg='green4',bd=5)
thirty_day_graph_frame.place(x=0, y=444)
thirty_days=dt.timedelta(days=43)
thirty_days_ago=today-thirty_days
five_yrs_graph_frame=Frame(fmain, width=645, height=400, bg='yellow2',bd=5)
five_yrs_graph_frame.place(x=655, y=444)
five_years=dt.timedelta(days=1825)
five_years_ago=today-five_years
def stock_info(stock_name):
stock=yf.Share(stock_name)
stock_price=stock.get_price()
name_price_label=Label(fmain, text=(stock_name,':', stock_price),font=("Times New Roman",23))
name_price_label.place(x=400, y=10)
day_high=quandl.get("WIKI/"+str(stock_name)+".2",start_date=str(today),end_date=str(today))
high_price_label=Label(fmain, text=(str(day_high)), font=("Times New Roman",20))
high_price_label.place(x=400, y=100)
thirty_day_data = quandl.get("WIKI/"+str(stock_name), start_date=str(thirty_days_ago), end_date=str(today),column_index=4) #So quandl.get gives a lot of info, so the column_index=4 is just getting closing prices
five_year_data = quandl.get("WIKI/"+str(stock_name),start_date=str(five_years_ago), end_date=str(today), column_index=4)
thirty_day_fig = plt.figure(figsize=(8,4))
plt.plot(thirty_day_data)
canvas = FigureCanvasTkAgg(thirty_day_fig, master=thirty_day_graph_frame)
plot_widget = canvas.get_tk_widget()
plot_widget.place(x=0,y=0)
five_year_fig=plt.figure(figsize=(8,4))
plt.plot(five_year_data)
canvas1=FigureCanvasTkAgg(five_year_fig, master=five_yrs_graph_frame)
plot_widget1=canvas1.get_tk_widget()
plot_widget1.place(x=1,y=0)
root.after(5000, stock_info, stock_name)
apple_button=Button(root,text='AAPL', command=lambda:stock_info('AAPL'))
tesla_button=Button(root,text='TSLA', command=lambda:stock_info('TSLA'))
google_button=Button(root,text='GOOG', command=lambda:stock_info('GOOG'))
apple_button.place(x=10, y=15)
tesla_button.place(x=10, y=45)
google_button.place(x=10,y=75)
root.mainloop()
The reason your graphs are plotted from the start is because of the way you assign commands to your buttons. One way to fix this is to assign the command as a lambda expression:
apple_button = Button(root, text='AAPL', command=lambda:stock_info('AAPL'))
To let your GUI update itself over time, you can create a loop using the root.after() method:
# Define the figure and canvas outside the loop
fig = plt.Figure()
a = fig.add_subplot(111)
canvas = FigureCanvasTkAgg(fig, master=f1)
canvas.get_tk_widget().grid()
def stock_info(stock_name):
# Get stock data and plot it on the GUI
...
a.cla()
a.plot(data)
canvas.draw()
# Schedule the function to call itself again after 5 seconds
root.after(5000, stock_info, stock_name)

Bokeh datetimetickformatter

I'm have some trouble with the DatetimeTickFormatter object from Bokeh. Plots randomly won't generate/update.
I have been searching and found this post at Bokeh, where it states that Plot not shown if DatetimeTickFormatter partially defined. I need some help with how to define it properly. Currently I'm doing this:
from bokeh.models.formatters import DatetimeTickFormatter
from bokeh.plotting import figure
DTF = DatetimeTickFormatter()
DTF.hours = ["%H:%M"]
DTF.days = ["%d/%m/%Y"]
DTF.months = ["%d/%m/%Y"]
DTF.years = ["%d/%m/%Y"]
and
p = figure()
p.xaxis.formatter = DTF
How should I define DTF “properly”?

matplotlib detect object upon mouse event

Is there any way to detect the matplotlib object the mouse is focused on ?
this a piece of code that illustrates what i want
self.canvas.mpl_connect("motion_notify_event", self.on_focus)
def on_focus(self, event):
# get mouse position in figure
figPos = (event.x,event.y)
# get mouse position in axes if focusing on an axes
axesPos = event.xdata, event.ydata
# get axes instance if mouse is focusing on an axes
axes = event.inaxes
# get object (any matplotlib object, Text, Box, ...) mouse is focused on
obj = event.??????
thanks
Try with Axes.hitlist:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10),range(10))
def on_focus(event):
print ax.hitlist(event)
fig.canvas.mpl_connect("motion_notify_event", on_focus)
plt.show()
But if you only want highlight you can use the built-in:
fig.canvas.mpl_connect("motion_notify_event",fig.canvas.onHilite)