I have a single column data frame constantly collecting data from an external device running in a while loop in real time. In order to plot the data frame I have used tkinter but due to its resource intensive issues I abandoned it, I have tried using matplotlib, but couldn't get it to update accordingly.
Any other suggestions or an example would be great
Okay so I found some help online and managed to neatly and efficiently display the data incoming from my sensors. So here are my steps to achieve the result, Open the python command window, and type python YourDataretrievingScript.py this will run your script of retrieving data from your sensors, just make sure you save it onto a csv file, then I run the following code and the animation window pops up
import pandas as pd
import numpy as np
from itertools import count
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.ticker import MaxNLocator
plt.style.use('fivethirtyeight')
index = count()
def animate(i):
data = pd.read_csv('Predict.csv')
x1 = data['Target']
x2 = data['Gesture']
plt.cla()
plt.plot(x1, label = 'Positions')
plt.plot(x2, label = 'Gesture')
plt.xticks([])
plt.legend(loc='upper left')
plt.tight_layout()
ani = FuncAnimation(plt.gcf(), animate, interval = 500)
plt.tight_layout()
plt.show()
I have plotted two different columns of data of the same csv file, and removed the xticks as per my specifications, if you don't want that just remove the plt.xticks([])
Related
I am trying to finish a task for a project and my task is to create a histogram of yearly returns of Dow Jones historical returns. I have uploaded a picture of the task and my progress below. The problem I have at this point is that I can't find a way to separate the years in the histogram as it shows in the task and I don't know how to modify the y-axix and the legend to show the information that is showing in the first picture.
Any help is appreciated
What I am trying to make and My progress so far
Here is my code:
# Importing packages
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
#setting the order
order=[-60,-50,-40,-30,-20,-10,
0,10,20,30,40,50,60,70]
#getting the data
dow_jones_returns = pd.read_csv('data/dow-jones-by-year-historical-annual-returns (2).csv')
dow_jones=pd.DataFrame(data=dow_jones_returns)
dow_jones['date']=pd.to_datetime(dow_jones['date'])
dow_jones['date']=pd.DatetimeIndex(dow_jones['date']).year
pd.to_numeric(dow_jones.value)
up_to_2019=dow_jones.iloc[0:99]
lastyear= dow_jones.iloc[-1]
#ploting the histogram
fig = plt.figure()
up_to_2019['value'].plot.hist(bins = order)
plt.show()
Hi to just give you some further directions,
Regarding the Textbox
the textbox looks like it contains the summary statistics of DataFrame.describe() + a few additional ones. You can create a textbox by utilzing a combination of .text() and .subplot()
I found this guide to be very useful for creating a textbox in a plot
Since we dont have the data,
here a pseudo code:
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
textstr = str(up_to_2019['value'].describe())
ax.hist(up_to_2019['value'], bins = order)
# these are matplotlib.patch.Patch properties
props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
# place a text box in upper left in axes coords
ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=10,
verticalalignment='top', bbox=props)
plt.show()
Regarding the y-axis:
1) Here is how you set the right label: plt.ylabel("Number of Observations\n(Probability in%)")
2) Than add the Ticks plt.yticks(np.arange(1,27))
Regarding the labels inside the bins
Thats rather tricky, one option, though definitely not advised would to also include the labels via the .text() method. I dont know if it helps but here is how you do this in R.
Also might helpful are these two links:
how-to-add-a-text-into-a-rectangle
Change color for the patches in a hist
Apparently calling plt.hist() has three return values one of which is callled patches. You can iterate over patches and i.e. change the color of these (see the link above) however I couldn't figure how to put a text to them.
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
x = [21,22,23,4,5,6,77,8,9,10,31,32,33,34,35,36,37,18,49,50,100]
num_bins = 5
n, bins, patches = plt.hist(x, num_bins, facecolor='blue', alpha=0.5)
for i,pat in enumerate(patches):
pat.set_test("Test") #this doesnt work sadly
I've created a map and I am reading in a CSV of latitude and longitude coordinates into a Pandas DataFrame. I've been successful in plotting multiple great arcs using a 'for' loop after reading in the DataFrame.
I am now trying to animate the multiple great arcs. The reason for the animation is to live update the plot when the CSV is updated. I eventually will use a SQL table for the DataFrame rather than a CSV, but I wanted to get the animation portion working first.
I read and watched multiple tutorials on matplotlib and animation. I've read the source documentation and attempted to apply multiple examples. I've been able to successfully animate a single great arc but can't seem to expand the code to multiple arcs.
Edit1: I want all great circle arcs from the file to be drawn on the map (I've got this part working). When a new set of latitude and longitude is added to the file I want it to update automatically within the same figure. I am trying to use this as a realtime display.
**Edit2: I've paired down the code as much as possible. It is minimal with a basic map, a few long/lat coordinates in a data frame and my attempt to animate the lines. I had to keep a CSV input as it is the only way to verify that the map updates once the CSV is updated.
The CSV contains the following:
sourcelon sourcelat destlon destlat
50.44 30.51 -80.84 35.22
52.52 13.4 -80.84 35.22
43.18 -22.97 -80.84 35.22
35.18 -22.97 -80.84 35.22
The arcs are being drawn, but are not being updated when the CSV is updated.
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import matplotlib.animation
# create new figure, axes instances.
fig=plt.figure()
# setup mercator map projection.
plt.figure(figsize=(27, 20))
m = Basemap(projection='mill', lon_0=0)
m.drawcoastlines(color='r', linewidth=1.0)
def animate(i):
df = pd.read_csv('c:/python/scripts/test2.csv', sep='\s*,\s*',header=0, encoding='ascii', engine='python'); df
for x,y,z,w in zip(df['sourcelon'], df['sourcelat'], df['destlon'], df['destlat']):
line, = m.drawgreatcircle(x,y,z,w,color='r')
line, = plt.plot([],[])
ani = matplotlib.animation.FuncAnimation(fig, animate, interval=1000)
plt.tight_layout()
plt.show()
I answered my own question. I am able to get the map to update when I add coordinates to the CSV. However, I cant remove them. I'll work on that as well.
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import matplotlib.animation
# setup mercator map projection.
fig = plt.figure(figsize=(27, 20))
m = Basemap(projection='mill', lon_0=0)
m.drawcoastlines(color='r', linewidth=1.0)
def animate(i):
df = pd.read_csv('c:/python/scripts/test2.csv', sep='\s*,\s*',header=0, encoding='ascii', engine='python'); df
for x,y,z,w in zip(df['sourcelon'], df['sourcelat'], df['destlon'], df['destlat']):
line, = m.drawgreatcircle(x,y,z,w,color='r')
ani = matplotlib.animation.FuncAnimation(fig, animate, interval=100)
plt.tight_layout()
plt.show()
I have multiple CSV files that I am trying to plot in same the figure to have a comparison between them. I already read some information about pandas problem not keeping memory plot and creating the new one every time. People were talking about using an ax var, but I do not understand it...
For now I have:
def scatter_plot(csvfile,param,exp):
for i in range (1,10):
df = pd.read_csv('{}{}.csv'.format(csvfile,i))
ax = df.plot(kind='scatter',x=param,y ='Adjusted')
df.plot.line(x=param,y='Adjusted',ax=ax,style='b')
plt.show()
plt.savefig('plot/{}/{}'.format(exp,param),dpi=100)
But it's showing me ten plot and only save the last one.
Any idea?
The structure is
create an axes to plot to
run the loop to populate the axes
save and/or show (save before show)
In terms of code:
import matplotlib.pyplot as plt
import pandas as pd
ax = plt.gca()
for i in range (1,10):
df = pd.read_csv(...)
df.plot(..., ax=ax)
df.plot.line(..., ax=ax)
plt.savefig(...)
plt.show()
As per the title, I'm wondering if it is possible to pause a matplotlib ArtistAnimation. I know it is possible to pause when using FuncAnimation, but I am not sure that that method can be applied to an ArtistAnimation.
An example of a working ArtistAnimation without pausing is
import matplotlib.pyplot as plt
from matplotlib.animation import ArtistAnimation
import numpy as np
fig, ax = plt.subplots()
ax.set(xlim=(0, 2*np.pi), ylim=(-1, 1))
x = np.linspace(0, 2*np.pi, 100)
ims = [] # Blank list that will contain all frames
for frame in range(50):
line, = ax.plot(x, np.sin(x + 0.1*frame), color='k')
# Add new element to list with everything that changes between frames
ims.append([line])
anim = ArtistAnimation(fig, ims, interval=100)
The following is not a complete solution, but maybe some way toward one. It requires IPython be used.
Using anim as defined in the question, I can enter anim._stop() to pause the animation. I can also use anim._step() as needed to see the next frames.
I'm not sure if it's possible to get the animation to start running again after these calls.
I have a loop to generate millions of histograms in python and i need to store them all in one folder in my laptop is there a way to save them all without the need of pressing save button each time a histogram generated?
Thanks
If you're using matplotlib, then what you are looking for is plt.savefig(). The documentation is here: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.savefig
For example:
import matplotlib.pyplot as plt
import numpy as np
# Some random data:
x = np.random.rand(100)
fig = plt.figure(1) # create a figure instance
ax = fig.add_subplot(111) # and axes
ax.hist(x) # plot the histogram
# plt.show() # this would show the plot, but you can leave it out
# Save the figure to the current path
fig.savefig('test_image.png')