Unexpected plots on matplotlib histograms - python-3.x

I am quite a beginner with matplotlib so apologies if this seems like a dumb question.
I have a csv file with weight values for individual neurons in the different layers of my deep learning model. As I have four layers in my model, the file structure looks like this:
weight_1,weight_2......weight_n
weight_1,weight_2......weight_n
weight_1,weight_2......weight_n
weight_1,weight_2......weight_n
I want to extract the weights from each layer and generate the distributions out of it. I already have a code for it and it's working but for some epochs, the histograms have some weird colors which look like more histograms. I am attaching a sample image with the question.
As you can see, there is some pinkish part which is masked by the blue bulk of the histogram. Can someone please help me to understand what is that?
My code currently looks like this (assume that my file is loaded in the reader):
for row in csv_reader:
a = np.array(row)
a_float = a.astype(np.float)
plt.hist(a_float,bins=20)
plt.xlabel("weight_range")
plt.ylabel("frequency")
Please note that FOUR different plots (images) are generated after finishing the loop as the csv file has four rows. I have only posted the sample image for one of them. I didn't try to plot all the rows in one graph.
EDIT
I reduced the number of bins and now it's more prominent. I am attaching another sample image.
SOLVED
Adding plt.figure() inside the loop solved it. Please check the comments and answer below for the details. The updated loop should be as follows:
for row in csv_reader:
a = np.array(row)
a_float = a.astype(np.float)
plt.figure()
plt.hist(a_float,bins=20)
plt.xlabel("weight_range")
plt.ylabel("frequency")
plt.close()

I was trying to reproduce your error, and most likely you are plotting several histograms in one plot:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
arrays = np.array([np.random.random() for i in range(200)]).reshape(2, 100)
fig = plt.figure()
ax = fig.add_subplot(111)
for array in arrays:
ax.hist(array, bins = 20)

Related

OpenCV - ArUco : detectMarkers failed identified some markers in a photos

I have pictures containing ArUco markers but I am unable to detect all of them with the detectMarkers function. Actually, I have many pictures : in some of them I can detect all the markers, in others I cannot and I don't really understand why.
I thought it was because of the quality of the photo, but it seems to be not so simple. Here's an example of my code :
import cv2
import matplotlib.pyplot as plt
from cv2 import aruco
aruco_dict = aruco.Dictionary_get(aruco.DICT_4X4_1000)
inputfile = 'EOS-1D-X-Mark-II_1201-ConvertImage.jpg'
frame = cv2.imread(inputfile)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
parameters = aruco.DetectorParameters_create()
corners, ids, rejectedImgPoints = aruco.detectMarkers(frame, aruco_dict, parameters=parameters)
frame_markers = aruco.drawDetectedMarkers(frame.copy(),rejectedImgPoints)
plt.figure(figsize=(20,10))
plt.imshow(frame_markers)
for i in range(len(ids)):
c = corners[i][0]
plt.plot([c[:, 0].mean()], [c[:, 1].mean()], "o", label = "id={0}".format(ids[i]))
plt.legend()
plt.show()
In this picture, 1 marker is not detected and I don't understand why.
I tried to tune the parameters of detectMarkers function manually with an interactive method thanks to jupyter notebook. There are many parameters and I found nothing that really helped me, except in some photos the reduction of polygonalApproxAccuracyRate.
The photo is orginally in 5472 x 3648 pixels but the one I send in this post is 2189 x 1459 pixels. Note that it doesn't work with the better resolution neither. Actually, I found in some photos that reducing the resolution help to detect the markers ... It's a contradiction but I think this is because the default parameters of the function are not adapted to my pictures, but I found no solution when tuning the parameters.
Another idea is to use the refineDetectMarkers function after calling detectMarkers. It uses the candidates that were found in detectMarkers but failed to be identified, and try to refine their identification. However, as far as I understood, I need to know where my markers should be in the picture and put it in refineDetectMarkers (as a board). In my situation, I don't know where the markers should be, otherwise I wouldn't take photos. The photos are used to observe precisely the evolution of their positions.
I am interested in any ideas you may have, thanks for reading !

Python - Pdf file with several figures in one page (not with subplots !!)

I'm trying to produce a pdf file (with PdfFile) containing several figures in one page.
The most obvious solution is to use subplots. However, in my case this is not possible because each plot is produced by a different function. For example, there is a function def plotPDF(inputData) that will plot a probability distribution function (PDF), and another function def plotCDF(inputData) that will plot a cumulative distribution function (CDF). My code contains up to 20 different functions that will produce different plots when they are called.
What I want to do is to select some of these plots and produce a pdf file where they are contained in the same page. Following the example of PDF and CDF, I would like to produce a pdf file which contains one page where both plots are next to each other (in a similar way to the subplots).
I have tried to do this with subplots, but I cannot directly call the function within a subplot. That is, the following code wouldn't work:
fig, ax = plt.subplots(nrows=1, ncols=2)
plt.subplot(1, 2, 1)
plotPDF(inputData)
plt.subplot(1, 2, 2)
plotCDF(inputData)
plt.show()
Does anybody know how to solve this issue ? I need to proceed like this because I need the plot functions to be independent for other purposes. Making subplots would mean changing this structure, and it would make the code less versatile.
Thanks in advance !
I don't know if there's a way to do what you are asking, maybe someone else will know...
but
the recommended way to write a plotting function is to pass a reference to an Axes object to the function, and write the function to use that axes to do the plotting.
so in your case:
def plotPDF(data, ax=None):
ax = ax or plt.gca() # if no axes, use current axes
plt.sca(ax) # set axes as current axes (important if you are using the pyplot API)
# the rest of the function goes here
def plotCDF(data, ax=None):
ax = ax or plt.gca()
plt.sca(ax)
(...)
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2)
plotPDF(inputData, ax=ax1)
plotCDF(inputData, ax=ax2)
plt.show()
Have you read this answer to a similar post? The answers in that post contain many ways to save an image into a pdf file, and only one (the matplotlib backend) requires subplots, as far as I know.
You can also save the files separately as png files, then use LaTeX / Word / another primitive way to arrange them into a pdf, which could be tedious.
Otherwise, could you maybe elaborate why using subplots wouldn't work with your functions? Maybe there is a way to use subplots, but then you'll need to show us the code.

Main figure legend outside of subplots

I have a number of subplots within a single figure. Each figure plots multiple lines that represent the same thing (represented by color) but in different situations (different subplots). I would like to create a legend at the base of the figure showing what the color of the line means. However, I running into a problem with getting the legend to not overlap the subplots and if I can adjust the axes, getting the legend to save.
I have tried a few different solutions with some help here but have been unable to adapt to subplots. Below is an example code that I am working with.
import numpy as np
import matplotlib.pyplot as plt
m1=1
m2=10
x=np.linspace(0,100,num=101,endpoint=True)
y1m1=m1*x**2
y2m1=m1*x**0.5
y1m2=m2*x**2
y2m2=m2*x**0.5
fig=plt.figure(figsize=(4,4))
ax1=fig.add_subplot(211)
ax1.plot(x,y1m1,'b',label=r'$x^2$')
ax1.plot(x,y2m1,'r',label=r'$\sqrt{x}$')
ax2=fig.add_subplot(212)
ax2.plot(x,y1m2,'b')
ax2.plot(x,y2m2,'r')
fig.legend(loc='lower center',ncol=2)
fig.tight_layout()
fig.savefig('examplefig.png',dpi=300)
plt.show()
My goal is to save the output to a png for a good figure.
This is one way of doing it using the suggestion provided here. The idea is to add the legend at position with respect to a given axis object. In your case, since you want to add the legend at the base, it is preferred you specify the position relative to ax2. Using ncol=2 is a matter of personal choice.
fig=plt.figure(figsize=(4,4))
ax1=fig.add_subplot(211)
l1, = ax1.plot(x,y1m1,'b')
l2, = ax1.plot(x,y2m1,'r')
ax2=fig.add_subplot(212)
ax2.plot(x,y1m2, 'b')
ax2.plot(x,y2m2, 'r')
ax2.legend(handles = [l1,l2] , labels=[r'$x^2$', r'$\sqrt{x}$'],
bbox_to_anchor=(0.7, -0.2), ncol=2)
fig.tight_layout()

How do I save each plot in individual pdf files while batch processing the x and y for the plot?

I came back to do some python work after not practicing it for a while. I feel like my issue may be a simple problem.. But I'm not sure how to address it. If you could share your insights, it would be a huge help. My current code is as the following:
import numpy as np
import matplotlib.pyplot as plt
import csv
import os
myfiles = os.listdir('input') #'all my input files are accessed
Then I do a whole bunch of math then generate my output files and save them in 'output' folder. Output folders consist output files of which each contains x and y columns as the code suggests in the following.
with open('output/'+file,'w') as f:
for a,b in zip(my_x,my_y):
f.write('{0:f},{1:f}\n'.format(a,b))
My biggest question lies here in the following, where I want to plot each output file and save them in pdf.
with open('output/'+file,'w') as f:
for a in zip(my_x,my_y):
fig, ax = plt.subplots()
ax.plot(my_x,my_y)
plt.xlim(3500,5700)
plt.show()
ax.set_ylabel('y_value')
ax.set_title('x')
fig.savefig()
The error message I get is
savefig() missing 1 required positional argument: 'fname'
Without the figure part of the code, the code runs fine (reads the input and generates the output files fine).
Any suggestions as to how to save figure for each of the output file?
If my code provided here is not sufficient enough to understand what's going on, let me know. I can provide more!
Would this do what you want?
with open('output/'+file,'w') as f:
for a in zip(my_x,my_y):
fig, ax = plt.subplots()
ax.plot(my_x,my_y)
plt.xlim(3500,5700)
plt.show()
ax.set_ylabel('y_value')
ax.set_title('x')
fig.savefig('output/' + file + '.pdf')

Python3x + MatPlotLib - Updating a chart?

I am new to both the python and matplotlib languages and working on something for my husband.
I hope you guys can help me out.
I would like to pull in a file using Open, read it, and update a graph with it's values.
Sounds easy enough right? Not so much in practice.
Here is what I have so far to open and chart the file. This works fine as it is to chart the file 1 time.
import matplotlib.pyplot as plt
fileopen = open('.../plotresults.txt', 'r').read()
fileopen = eval(fileopen) ##because the file contains a dict and security is not an issue.
print(fileopen) ## So I can see it working
for key,value in fileopen.items():
plot1 = value
plt.plot(plot1, label=str(key))
plt.legend()
plt.show()
Now I would like to animate the chart or update it so that I can see changes to the data. I have tried to use matplotlib's animation feature but it is advanced beyond my current knowledge.
Is there a simple way to update this chart, say every 5 minutes?
Note:
I tried using Schedule but it breaks the program (maybe a conflict between schedule and having matplotlib figures open??).
Any help would be deeply appreciated.
Unfortunately you will just waste time trying to get a clean solution without either using matplotlib's animation feature or using the matplotlib OO interface.
As a dirty hack you can use the following:
from threading import Timer
from matplotlib import pyplot as plt
import numpy
# Your data generating code here
def get_data():
data = numpy.random.random(100)
label = str(data[0]) # dummy label
return data, label
def update():
print('update')
plt.clf()
data, label = get_data()
plt.plot(data, label=label)
plt.legend()
plt.draw()
t = Timer(0.5, update) # restart update in 0.5 seconds
t.start()
update()
plt.show()
It spins off however a second thread by Timer. So to kill the script, you have to hit Ctrl-C twice on the console.
I myself would be interested if there is a cleaner way to do this in this simple manner in the confines of the pyplot machinery.
Edits in italic.

Resources