I want to plot line graph row my row & I want the previous line to be updated by the next line (on the same frame).
Here's the example of the input:
Here's the code that I have:
def openB():
bmFile = filedialog.askopenfile(mode='r',
filetypes=(("CSV file", "*.csv"), ("All files", "*.*")),
title="Select a CSV file")
bmFile2 = pd.read_csv(bmFile, header=[2])
selectCol = bmFile2.iloc[0:,3:]
selectCol.T.plot()
plt.show()
I want to plot each row, that's why I am using Transpose method on selectCol.
In order to plot row by row (dynamically changing), what function should I do?
FuncAnimation or for loop (range)?
and How?
Thank you.
Greatly appreciated :)
You can use the plt.clf and plt.draw to plot it dynamically.
As follows for example:
import matplotlib.pyplot as plt
import numpy as np
file = np.random.normal(5,5,(1000,100))
for row in file:
plt.clf() # Clear the current figure
plt.plot(row) # Calculate and plot all you want
plt.draw()
plt.pause(0.1) # Has to pause for a non zero time
plt.show() # When all is done
PS: ax.clear() will clear the axis while plt.clf() will clear the entire figure.
This shows how to dynamically plot each row:
with open('file.csv','r') as f:
lines = f.read().splitlines()
for line in lines:
y = line.split(',')[2:]
x = np.linspace(0,1,num=len(y))
plt.plot(x,y)
I know this doesn't animate, but I it helps the dynamic issue.
Related
I have two .txt files and with them, I would like to plot the graphs corresponding to each file in the same window. I managed to plot only one. Using the code below:
import matplotlib.pyplot as plt
timecap = []
qtd = []
# f = open('dataset.txt', 'r')
for line in open('pkts_by_src.txt', 'r'):
lines = [i for i in line.split(',')]
timecap.append(lines[0])
qtd.append(int(lines[1]))
plt.title("Capture")
plt.xlabel('time cap')
plt.ylabel('qtd')
plt.yticks(qtd)
plt.plot(timecap, qtd, marker='o', c='g')
plt.show()
The file is in this format:
22:40:16,2
22:40:20,1
22:40:20,2
22:40:23,1
22:40:23,4
22:40:23,6
22:40:23,8
Can you give me a tip? I'm a beginner in python
Try using the subplot function as shown. After calling it make your graph the repeat, at the end do show(), you can look at the matplotlib documentation for specific parameters.
plt.subplot(211)
for line in open('pkts_by_src.txt', 'r'):
lines = [i for i in line.split(',')]
...
plt.subplot(212)
for line in open('wordlist2.txt', 'r'):
lines = [i for i in line.split(',')]
...
plt.show()
Without plt.legend() called, the plot gets displayed. With it, I just get:
<matplotlib.legend.Legend at 0x1189a404c50>
I'm working in JupyterLab, Python 3, Anaconda
I do not understand what is preventing legend from displaying. Without the last for loop iterating through xarray, i.e. if I load just one spectrum to plot, legend works fine. Any ideas? Thanks!
Here is the code:
import colour
from colour.plotting import *
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib
import scipy.integrate as integrate
from scipy import interpolate
### Read Spectrum file ###
xarray = []
yarray = []
while True:
# Separator in CSV
separator = input("Separator: [, or tab or semicolon]")
if separator in {',','comma'}:
separator = ','
elif separator in {'tab','TAB'}:
separator = '\t'
elif separator in {';','semicolon'}:
separator = ';'
else:
print("Separator must be one of the listed")
# Header in CSV
headerskip = input("Header [y/n]")
if headerskip in {'y','yes','Y','Yes','YES'}:
headerskip = 1
elif headerskip in {'n','no','N','No','NO'}:
headerskip = 0
else:
print("Header?")
# Choose CSV file
filename = input("Filename")
try:
spectrum = pd.read_csv(filename, sep = separator, header = None, skiprows = headerskip, index_col=0)
except FileNotFoundError:
print("Wrong file or file path")
# Convert to our dictionary
spec = spectrum[1].to_dict() #functional dictionary
sample_sd_data = {int(k):v for k,v in spec.items()} # changes index to integer
# Do color calculations
sd = colour.SpectralDistribution(sample_sd_data)
cmfs = colour.STANDARD_OBSERVERS_CMFS['CIE 1931 2 Degree Standard Observer']
illuminant = colour.ILLUMINANTS_SDS['D65']
XYZ = colour.sd_to_XYZ(sd, cmfs, illuminant) #tristimulus values.
print(XYZ)
xy = colour.XYZ_to_xy(XYZ) # chromaticity coordinates
x, y = xy
print(xy)
xarray.append(x)
yarray.append(y)
# Query to add another file
addfile = input("Add another spectrum [y,n]")
if addfile in {'y','yes','Y','Yes','YES'}:
print("adding another file")
elif addfile in {'n','no','N','No','NO'}:
print("done with adding files")
break
else:
print("Add another file? Breaking loop")
break
# Plotting the *CIE 1931 Chromaticity Diagram*.
# The argument *standalone=False* is passed so that the plot doesn't get
# displayed and can be used as a basis for other plots.
#plot_single_sd(sd)
print(xarray)
print(yarray)
plot_chromaticity_diagram_CIE1931(standalone=False)
# Plotting the *CIE xy* chromaticity coordinates.
for i in range(len(xarray)):
x = xarray[i]
y = yarray[i]
plt.plot(x, y, '-p', color='gray',
markersize=15, linewidth=4,
markerfacecolor='None',
markeredgecolor='gray',
markeredgewidth=2,
label=str(i))
plt.plot(.3,.3, '-o', label='test')
# Customizing plot
plt.grid(True, linestyle=':')
plt.axis('equal') # disable this to go x to zero, however it will hide 500nm label
plt.xlim(0,.8)
plt.ylim(0,.9)
#plt.legend(framealpha=1, frameon=True, handlelength=0) # set handlelength to 0 to destroy line over the symbol
You need to call the magic function %matplotlib notebook or %matplotlib inline after your imports in jupyter.
I'm trying to make a program that will create a descending series of plots based on given files containing an n*2 matrix of numerical values (they more or less share an x-axis, and they're close enough on the y-axis that they need to be manipulated to avoid overlap).
Right now, the way it works is to read in the files one at a time with fileinput, add a constant to the values in column two (arbitrary so long as the constant splits each plot; I do it by multiplying the number of files by two, and decrementing by two each plot so they get split), then add the manipulated values to two master lists (for x and y), which are plotted at the end by matplotlib.
I have it doing very close to exactly what I want, but it has some odd lines connecting the end of one file to the beginning of the next, and I'd like to know how to remove them.
Here's the relevant part of the code:
mpl.suptitle(spectitle, fontsize=16)
mpl.xlabel('wavelength (A)', fontsize=14)
mpl.ylabel('flux (erg s^-1 cm^-2)', fontsize=14)
with open(filelist) as infile:
allfiles = [line.rstrip('\n') for line in open(filelist)]
multiplier = len(allfiles)
multiplier *= 2
for line in fileinput.input(allfiles):
filename = fileinput.filename()
waveN, fluxN = np.loadtxt(filename, usecols=[0,1], unpack=True)
fluxCalc = np.array(fluxN)
fluxCalc += multiplier
multiplier -= 2 #decrease multiplier, causing next output specturm to be placed below the one just calculated
wavelenAll.extend(waveN)
fluxCalc.tolist()
fluxAll.extend(fluxCalc)
fileinput.nextfile()
mpl.plot(wavelenAll, fluxAll)
mpl.savefig('allspec.png')
mpl.show()
I can add an image of the output in a few hours. Thanks for any help in advance.
Try something like:
import matplotlib.pyplot as plt
import numpy as np
filelist = []
spectitle = 'spectrum'
with open(filelist) as infile:
allfiles = [line.rstrip('\n') for line in open(filelist)]
all_flux, all_wavelen = [], []
# just get the data from the file and accumulate in a list
# which assumes you want these lists for something else
for fname in allfiles:
waveN, fluxN = np.loadtxt(fname, usecols=[0, 1], unpack=True)
all_flux.append(fluxN)
all_wavelen.append(waveN)
fig, ax = plt.subplots()
fig.suptitle(spectitle, fontsize=16)
ax.set_xlabel('wavelength (A)', fontsize=14)
ax.set_ylabel('flux (erg s^-1 cm^-2)', fontsize=14)
# loop over the data and plot
for wv, flux, shift in zip(all_wavelen, all_flux,
range(1, len(allfiles) + 1)[::-1]):
# do the shift as late as possible so you do not accidentally reuse
# cosmetically shifted data for computing something
ax.plot(wv, flux + shift, color='b')
fig.savefig('allspec.png')
plt.show()
It must be in the data or caused by its wrong postprocessing. It is hard to say more unless we see the data. Try to plot it without first of last elements, i.e. like mpl.plot(wavelenAll[1:-1], fluxAll[1:-1])
This is from Chapter 2 in the book Machine Learning In Action and I am trying to make the plot pictured here:
The author has posted the plot's code here, which I believe may be a bit hacky (he also mentions this code is sloppy since it is out of the book's scope).
Here is my attempt to re-create the plot:
First, the .txt file holding the data is as follows (source: "datingTestSet2.txt" in Ch.2 here):
40920 8.326976 0.953952 largeDoses
14488 7.153469 1.673904 smallDoses
26052 1.441871 0.805124 didntLike
75136 13.147394 0.428964 didntLike
38344 1.669788 0.134296 didntLike
...
Assume datingDataMat is a numpy.ndarray of shape `(1000L, 2L) where column 0 is "Frequent Flier Miles Per Year", column 1 is "% Time Playing Video Games", and column 2 is "liter of ice cream consumed per week", as shown in the sample above.
Assume datingLabels is a list of ints 1, 2, or 3 meaning "Did Not Like", "Liked in Small Doses", and "Liked in Large Doses" respectively - associated with column 3 above.
Here is the code I have to create the plot (full details for file2matrix are at the end):
datingDataMat,datingLabels = file2matrix("datingTestSet2.txt")
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot (111)
plt.xlabel("Freq flier miles")
plt.ylabel("% time video games")
# Not sure how to finish this: plt.legend([1, 2, 3], ["did not like", "small doses", "large doses"])
plt.scatter(datingDataMat[:,0], datingDataMat[:,1], 15.0*np.array(datingLabels), 15.0*np.array(datingLabels)) # Change marker color and size
plt.show()
The output is here:
My main concern is how to create this legend. Is there a way to do this without needing a direct handle to the points?
Next, I am curious whether I can find a way to switch the colors to match those of the plot. Is there a way to do this without having some kind of "handle" on the individual points?
Also, if interested, here is the file2matrix implementation:
def file2matrix(filename):
fr = open(filename)
numberOfLines = len(fr.readlines())
returnMat = np.zeros((numberOfLines,3)) #numpy.zeros(shape, dtype=float, order='C')
classLabelVector = []
fr = open(filename)
index = 0
for line in fr.readlines():
line = line.strip()
listFromLine = line.split('\t')
returnMat[index,:] = listFromLine[0:3] # FFmiles/yr, % time gaming, L ice cream/wk
classLabelVector.append(int(listFromLine[-1]))
index += 1
return returnMat,classLabelVector
Here's an example that mimics the code you already have that shows the approach described in Saullo Castro's example.
It also shows how to set the colors in the example.
If you want more information on the colors available, see the documentation at http://matplotlib.org/api/colors_api.html
It would also be worth looking at the scatter plot documentation at http://matplotlib.org/1.3.1/api/pyplot_api.html#matplotlib.pyplot.scatter
from numpy.random import rand, randint
from matplotlib import pyplot as plt
n = 1000
# Generate random data
data = rand(n, 2)
# Make a random array to mimic datingLabels
labels = randint(1, 4, n)
# Separate the data according to the labels
data_1 = data[labels==1]
data_2 = data[labels==2]
data_3 = data[labels==3]
# Plot each set of points separately
# 's' is the size parameter.
# 'c' is the color parameter.
# I have chosen the colors so that they match the plot shown.
# With each set of points, input the desired label for the legend.
plt.scatter(data_1[:,0], data_1[:,1], s=15, c='r', label="label 1")
plt.scatter(data_2[:,0], data_2[:,1], s=30, c='g', label="label 2")
plt.scatter(data_3[:,0], data_3[:,1], s=45, c='b', label="label 3")
# Put labels on the axes
plt.ylabel("ylabel")
plt.xlabel("xlabel")
# Place the Legend in the plot.
plt.gca().legend(loc="upper left")
# Display it.
plt.show()
The gray borders should become white if you use plt.savefig to save the figure to file instead of displaying it.
Remember to run plt.clf() or plt.cla() after saving to file to clear the axes so you don't end up replotting the same data on top of itself over and over again.
To create the legend you have to:
give labels to each curve
call the legend() method from the current AxesSubplot object, which can be obtained using plt.gca(), for example.
See the example below:
plt.scatter(datingDataMat[:,0], datingDataMat[:,1],
15.0*np.array(datingLabels), 15.0*np.array(datingLabels),
label='Label for this data')
plt.gca().legend(loc='upper left')
How do I open multiple text files from different directories and plot them on a single graph with legends?
This is relatively simple if you use pylab (included with matplotlib) instead of matplotlib directly. Start off with a list of filenames and legend names, like [ ('name of file 1', 'label 1'), ('name of file 2', 'label 2'), ...]. Then you can use something like the following:
import pylab
datalist = [ ( pylab.loadtxt(filename), label ) for filename, label in list_of_files ]
for data, label in datalist:
pylab.plot( data[:,0], data[:,1], label=label )
pylab.legend()
pylab.title("Title of Plot")
pylab.xlabel("X Axis Label")
pylab.ylabel("Y Axis Label")
You also might want to add something like fmt='o' to the plot command, in order to change from a line to points. By default, matplotlib with pylab plots onto the same figure without clearing it, so you can just run the plot command multiple times.
Assume your file looks like this and is named test.txt (space delimited):
1 2
3 4
5 6
7 8
Then:
#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt
with open("test.txt") as f:
data = f.read()
data = data.split('\n')
x = [row.split(' ')[0] for row in data]
y = [row.split(' ')[1] for row in data]
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax1.set_title("Plot title...")
ax1.set_xlabel('your x label..')
ax1.set_ylabel('your y label...')
ax1.plot(x,y, c='r', label='the data')
leg = ax1.legend()
plt.show()
I find that browsing the gallery of plots on the matplotlib site helpful for figuring out legends and axes labels.
I feel the simplest way would be
from matplotlib import pyplot;
from pylab import genfromtxt;
mat0 = genfromtxt("data0.txt");
mat1 = genfromtxt("data1.txt");
pyplot.plot(mat0[:,0], mat0[:,1], label = "data0");
pyplot.plot(mat1[:,0], mat1[:,1], label = "data1");
pyplot.legend();
pyplot.show();
label is the string that is displayed on the legend
you can plot as many series of data points as possible before show() to plot all of them on the same graph
This is the simple way to plot simple graphs. For other options in genfromtxt go to this url.