I got this CSV:
and this code:
import csv
import numpy as np
import matplotlib.pyplot as plt
filename = '../dataset/data_validation/annotationValidation.csv'
fields = ['Image', 'Color', 'Validator']
imageIds = ['photo-1612694875299-4c379cb55ae2.jpg', 'photo-1611308382871-971045fcff4e.jpg', 'photo-1621329564823-1e0555fea622.jpg', 'photo-1624828002048-2681f0e67aed.jpg']
with open(filename, 'r') as csv_file:
dict_reader = csv.DictReader(csv_file)
headers = dict_reader.fieldnames
for imageId in imageIds:
# Color
blackAndWhite, colorful = 0, 0
count = 0
for row in dict_reader:
count = count + 1
print(count)
if imageId == row['Image']:
print(imageId)
# Color
if (row['Color']) == 'Black & White':
blackAndWhite = blackAndWhite + 1
else:
colorful = colorful + 1
labels = ['Black & White', 'Colorful']
counts = np.array([blackAndWhite, colorful])
# creating the bar plot
plt.barh(labels, counts, color='maroon')
plt.xlabel("No of Answers")
plt.ylabel("Labels")
plt.title("Metrics")
plt.ioff()
plt.show()
and I am trying to plot a bar for each image I find on my csv. In this example I have 3 images on my imageIds array, so 3 plots in total, showing the distribution between colorful and b&w.
The thing is, only my first plot appears, all the others are coming empty.
I am not sure if it something with my 2 loops or a matplotlib related thing.
Thank you
Ok found the error. I need to open csv before the second loop, meaning reopening csv from the start, cause probably once all the lines are read then the csv closes. Thank you all
Related
In Short:
I want to change the color of blue marker in the graph. So that I can do comparison with other plots easily.
You can download the data files and script from this link
Problem Explanation
I have two data files, full.dat and part.dat(Note: part.dat is also there in full.dat).
I got the plotting scripts from the internet, and it is working very well. But as a noob in Python and Matplotlib, I am facing difficulties in changing the color of part.dat.
Please see the graph first, then the following scripts.
Script-1: Function and definitions: let's say: "func.py"
# This was written by Levi Lentz for the Kolpak Group at MIT
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
import matplotlib.gridspec as gs
import sys
#This function extracts the high symmetry points from the output of bandx.out
def Symmetries(fstring):
f = open(fstring,'r')
x = np.zeros(0)
for i in f:
if "high-symmetry" in i:
x = np.append(x,float(i.split()[-1]))
f.close()
return x
# This function takes in the datafile, the fermi energy, the symmetry file, a subplot, and the label
# It then extracts the band data, and plots the bands, the fermi energy in red, and the high symmetry points
def bndplot(datafile_full,datafile,fermi,symmetryfile,subplot,**kwargs):
if 'shift_fermi' in kwargs:
bool_shift_efermi = kwargs['shift_fermi']
else:
bool_shift_efermi = 0
if 'color' in kwargs:
color_bnd=kwargs['color']
else:
color_bnd='black'
if 'linestyle' in kwargs:
line_bnd=kwargs['linestyle']
else:
line_bnd='solid'
z = np.loadtxt(datafile_full) #This loads the full.dat file
x = np.unique(z[:,0]) #This is all the unique x-points
[a,b,w]=np.loadtxt(datafile,unpack=True) #Weight
bands = []
bndl = len(z[z[:,0]==x[1]]) #This gives the number of bands in the calculation
Fermi = float(fermi)
if bool_shift_efermi:
fermi_shift=Fermi
else:
fermi_shift=0
axis = [min(x),max(x)]
for i in range(0,bndl):
bands.append(np.zeros([len(x),2])) #This is where we storre the bands
for i in range(0,len(x)):
sel = z[z[:,0] == x[i]] #Here is the energies for a given x
test = []
for j in range(0,bndl): #This separates it out into a single band
bands[j][i][0] = x[i]
#bands[j][i][1] = np.multiply(sel[j][1],13.605698066)
bands[j][i][1] = sel[j][1]
#Here we plots the bands
for i in bands:
subplot.plot(i[:,0],i[:,1]-fermi_shift,color=color_bnd,linestyle=line_bnd, linewidth=0.7,alpha=0.5)
# plt.scatter(a,b-fermi_shift,c=w,cmap='viridis',alpha=0.5)
# plt.colorbar()
if 'legend' in kwargs:
#empty plot to generate legend
subplot.plot([None],[None],color=color_bnd,linestyle=line_bnd,label=kwargs['legend'])
temp = Symmetries(symmetryfile)
for j in temp: #This is the high symmetry lines
x1 = [j,j]
subplot.axvline(x=j,linestyle='dashed',color='black',alpha=0.75)
subplot.plot([min(x),max(x)],[Fermi-fermi_shift,Fermi-fermi_shift],color='red',linestyle='dotted')
subplot.set_xticks(temp)
subplot.set_xticklabels([])
if 'name_k_points' in kwargs:
if len(kwargs['name_k_points'])==len(temp):
subplot.set_xticklabels(kwargs['name_k_points'])
if 'range' in kwargs:
range_plot=kwargs['range']
subplot.set_ylim([range_plot[0],range_plot[1]])
subplot.set_xlim([axis[0],axis[1]])
subplot.set_xlabel('k')
subplot.set_ylabel('E-E$_f$')
plt.scatter(a,b-fermi_shift,s=70*np.array(w))
if 'legend' in kwargs:
plt.legend()
script-2 Plotting script: let's say: "plot.py"
#!/usr/bin/python3
from func import *
El='el'
orb='orb'
plt.rcParams["figure.figsize"]=(4,15)
datafile_full='bands.dat.gnu'
#datafile=El+'_'+orb+'.dat.all'
datafile=El+'_'+orb+'.dat.all'
fermi = 10.2382
symmetryfile='band.out'
bool_shift_efermi= True
fig, ax = plt.subplots()
#bndplot(datafile,fermi,symmetryfile,ax)
bndplot(datafile_full,datafile,fermi,symmetryfile,ax,shift_fermi=1,color='black',linestyle='solid',name_k_points=['K','G','M','K','H','A','L','H'], legend=El+', '+orb+'-orbital')
#ax.set_ylim(-5,5)
ax.set_ylim(-10,12)
fig.set_figheight(6)
fig.set_figwidth(4)
plt.rcParams.update({'font.size': 22})
fig.savefig("el-orb.eps")
plt.show()
In script-2, there is an option to change the color, however I want to change the color of blue marker/solid-circles(please see the graph) so that I can compare with other graphs.
Whenever I change the color, it changes the line color only.
Please help me out I am trying to understand Matplotlib uses and examples from past few hrs However as a noob I was not able to figure out how to do.
....
1.I am making a python code that creates plots of data imported from a CITIfile. I want to run the code such that each plot made will have a different title. For example, plot one will have the title S11 Log Magnitude, the second plot will have the title S12 Log Magntitude, the third plot S12 Log Magnitude, and the fourth plot with the title S22 Log magnitude. The code I have written now will produce titles 0, 1, 2, and 3, using plt.title(str(i)). What modifications can I make to this code so that it will produce the desired plot titles in this sequence?
....
# modified based on https://github.com/feph/citidata
import citidata
import glob
import numpy as np
from numpy import *
import matplotlib.pyplot as plt
keyslist = [] # data name
datalist = [] # data arrays
M = N = 0
all_my_files = glob.glob("*.citi")
for filename in all_my_files:
M += 1
print("=== %s ===" % filename)
citi_file = citidata.genfromfile(filename)
for package in citi_file.packages:
print(package)
print(package.indep)
#print(package.deps) # suppress screen output
for key in package.deps:
N += 1
value = package.deps[key] # get data field
keyslist.append(key) # append key
datalist.append(value['data']) # append np array data
print('\n ', M, 'files read;', N, 'datasets recorded.')
print('dataset : name')
#plt.figure(0)
w = []
x = np.linspace(8, 12, 201)
for i in range(N):
fig = plt.figure(i)
print(i, ':', keyslist[i])
y = datalist[i] # data
# print(y)
test = np.abs(y)
f = sqrt(test)
mag = 20*log10(f)
print(mag)
# [S11, S21, S12,S22]
# y = np.append(mag)
plt.xlabel('Frequancy (Hz')
plt.ylabel('Log Magnitude (dB')
plt.plot(x, mag)
plt.title(str(i))
I think the only way to do this is by dictionary as there is no sequence in the name. Create a dictionary with integer key and the value being the name of the graph in the global scope:
name_dict = {
0: "S11 Log Magnitude",
1: "S12 Log Magntitude",
2: "S12 Log Magnitude",
3: "S22 Log magnitude"
}
After that, you just change the last code line to
plt.title(name_dict[i])
I hope this was helpful!
EDIT 1:
Sorry, I have changed the key number to start from 0.
EDIT 2:
Forgot commas in the dictionary and just added them
I have a set of .txt named "occupancyGrid_i", i being a number from 0-100.
What I'd like to do is to open every one of them and show them for 3 seconds. The data of the .txt is a [N x M] matrix.
import numpy
import matplotlib.pyplot as plt
import time
while True:
matrix = numpy.loadtxt('res/matrix_' + str(i) + '.txt')
plt.clf()
plt.imshow(matrix)
plt.show()
time.sleep(3)
i=i+1
What I have done so far doesn't seem to be enough. What am I doing wrong?
You can try something like this, adapting the code suggested in this answer:
import os
import numpy as np
import pylab as plt
N_IMAGES = 100
VMIN, VMAX = 0, 1 # range of values in matrices
i = 0
while True:
if i < N_IMAGES:
path = 'res/matrix_' + str(i) + '.txt'
if os.path.exists(path): # check if file exists
matrix = np.loadtxt('matrices/matrix_' + str(i) + '.txt')
plt.imshow(matrix, vmin=VMIN, vmax=VMAX)
plt.title("Matrix {}".format(i))
plt.pause(3)
i += 1
else:
# terminate you program or start from the beginning
break
# i = 0
# continue
I dont know what exactly your goal is. But to display text in matplotlib you can use text from pyplot.
`
import numpy
import matplotlib.pyplot as plt
import time
for i in range(1,5):
s = ''
with open(str(i)+'.txt','r') as f:
s=f.read()
plt.text(0.5, 0.67,s,transform=plt.gca().transAxes)
plt.show()
time.sleep(3)
First 2 argument (0.5 ,0.67) are cordinate of displayed text.
I think you should find some other way of displaying text. Just print them on your console, plotting them is not the best way to represent text data.
I have a csv file which contains four columns. The first column in time, the second, third and fourth columns are Accelerometer readings. I want to plot Time on X-Axis and the Accelerometer reading on Y-Axis.
Sample Data:
0 1.0969 9.7721 0.614
20 1.1146 9.7501 0.7444
40 1.1146 9.7501 0.7444
60 1.0124 9.7151 0.7169
79 1.0124 9.7151 0.7169
100 1.0927 9.7324 0.7356
120 1.0927 9.7324 0.7356
Here is what I have so far.
from numpy import genfromtxt
import csv
import matplotlib.pyplot as plt
#import numpy as np
# Open the desired file for reading
f = open('walk-shoe.csv', "rb")
# create a object of csv class and read the file
# use ',' as a delimiter
reader = csv.reader(f, delimiter=',')
time_row = 0
accel_1_row = 0
accel_2_row = 0
accel_3_row = 0
time = []
accel_1 = []
accel_2 = []
accel_3 = []
# create a list of 'Time in ms'
for row in reader:
# Skip the first row
time_row = time_row + 1
if time_row == 1:
continue
time.append(row[0])
accel_1.append(row[1])
accel_2.append(row[2])
accel_3.append(row[3])
# print the contents of the list
# print time
#print accel_1
#print accel_2
#print accel_3
# append all the list accelerometer list together
final_accel = []
final_accel.append(accel_1)
final_accel.append(accel_2)
final_accel.append(accel_3)
#print final_accel
# plot the graph
for i in range(len(final_accel)):
plt.plot(time,[pt[i] for pt in final_accel],label = 'id %s'%i)
plt.legend()
plt.show()
I want to plot all the sensor readings on one graph on y axis and time in x axis
You seem to be importing numpy in the code you give, therefore I will take that to mean that library is available to you. Numpy lets you read in data very easily using numpy.loadtxt().
You can then create a for loop which goes through columns 1 to 3 and plots data against column 0 (time).
import numpy as np
import matplotlib.pyplot as plt
data = np.loadtxt('walk-shoe.csv', delimiter=',', dtype=float)
print (data)
#[[ 0. 1.0969 9.7721 0.614 ]
# [ 20. 1.1146 9.7501 0.7444]
# [ 40. 1.1146 9.7501 0.7444]
# [ 60. 1.0124 9.7151 0.7169]
# [ 79. 1.0124 9.7151 0.7169]
# [ 100. 1.0927 9.7324 0.7356]
# [ 120. 1.0927 9.7324 0.7356]]
for i in range(1,data.shape[1]):
plt.plot(data[:,0], data[:,i], label='id %s' %i)
plt.legend()
plt.show()
I am reading the parameters from different CSV files and creating the graphs after comparing the parameters across the CSVs. The problem is only last graph is getting pasted in PDF for the last parameter.
with PdfPages('example.pdf') as pdf:
for arg in sys.argv[1:]:
file_reader= open(arg, "rt", encoding='ascii')
read = csv.reader(file_reader)
for row in read:
if operation_OnDut in row:
column_Result = row[10]
resultOfOperations_OnDut_List.append(column_Result)
buildNumber = row[0]
buildName_List.append(buildNumber)
N = len(resultOfOperations_OnDut_List)
ind = np.arange(N)
#Draw graph for operations performed in that TEST CASE
y = resultOfOperations_OnDut_List
width = .1
fig, ax = plt.subplots()
plt.bar(ind, y, width, label = column_Parameters, color="blue")
plt.xticks(ind, buildName_List)
plt.title("Performance and Scale")
plt.ylabel('Result of Operations')
plt.xlabel('Execution Builds')
plt.legend()
plt.tight_layout()
pdf.savefig()
plt.close()
resultOfOperations_OnDut_List = []
buildName_List = []
You probably got the indentation wrong...
Try
with PdfPages('example.pdf') as pdf:
for arg in sys.argv[1:]:
file_reader= open(arg, "rt", encoding='ascii')
read = csv.reader(file_reader)
for row in read:
if operation_OnDut in row:
column_Result = row[10]
....
# one level deeper
N = len(resultOfOperations_OnDut_List)
ind = np.arange(N)
#Draw graph for operations performed in that TEST CASE
...
Note that the section starting with N = len(resultOfOperations_OnDut_List) has been shifted four spaces to the left to be within the first for loop. If you want it to be within the second for loop add four more spaces.