MatPlotLib printing out graphs on the same line next to each other - python

So I am making a program that reads in multiple two dimensional lists and plots them as step graph functions. I want to print out each set of graphs side by side like so (I made the graphs different colors just to differentiate the two):
Desired Output
However my code right now makes these two sets overlap each other instead, like so:
Actual Output
I believe it might have something to do with my "t" variable in plotPoints but I am not sure what I need to do. Any help would be greatly appreciated.
# supress warning message
import warnings; warnings.simplefilter("ignore")
# extension libraries
import matplotlib.pyplot as plt
import numpy as np
def plotPoints(bits, color):
for i in range(len(bits)):
data = np.repeat(bits[i], 2)
t = 0.5 * np.arange(len(data))
plt.step(t, data + i * 3, linewidth=1.5, where='post', color=color)
# Labels the graphs with binary sequence
for tbit, bit in enumerate(bits[i]):
plt.text(tbit + 0.3, 0.1 + i * 3, str(bit), fontsize=6, color=color)
def main():
plt.ylim([-1, 32])
set1 = [[0, 0, 0, 1, 1, 0, 1, 1], [0, 0, 1, 0, 1, 1, 0, 0], [1, 1, 0, 0, 1, 0, 0, 0]]
set2 = [[1, 1, 1, 0, 0, 1, 0, 0], [1, 1, 0, 1, 0, 0, 1, 1], [0, 0, 1, 1, 0, 1, 1, 1]]
plotPoints(set1, 'g')
plotPoints(set2, 'b')
# removes the built in graph axes and prints line every interation
plt.gca().axis('off')
plt.ylim([-1, 10])
plt.show()
main()

You can add some offset to t.
import matplotlib.pyplot as plt
import numpy as np
def plotPoints(bits, color, offset=0):
for i in range(len(bits)):
data = np.repeat(bits[i], 2)
t = 0.5 * np.arange(len(data)) + offset
plt.step(t, data + i * 3, linewidth=1.5, where='post', color=color)
# Labels the graphs with binary sequence
for tbit, bit in enumerate(bits[i]):
plt.text(tbit + 0.3 +offset, 0.1 + i * 3, str(bit), fontsize=6, color=color)
def main():
set1 = [[0, 0, 0, 1, 1, 0, 1, 1], [0, 0, 1, 0, 1, 1, 0, 0], [1, 1, 0, 0, 1, 0, 0, 0]]
set2 = [[1, 1, 1, 0, 0, 1, 0, 0], [1, 1, 0, 1, 0, 0, 1, 1], [0, 0, 1, 1, 0, 1, 1, 1]]
plotPoints(set1, 'g')
plotPoints(set2, 'b', offset=len(set1[0]))
# removes the built in graph axes and prints line every interation
plt.gca().axis('off')
plt.ylim([-1, 10])
plt.show()
main()

Related

Is there a way to plot matrix elements like a heat map?

I'm programming a code where I use a matrix full of 0's and 1's, the idea is to represent a galaxy, so the 0's are like the void and the 1's will be solar systems (for now), later I intend to add more elements. So, I was wondering if there's a way to plot this elements sorta like a heat map (1 = red and 0 = blue). I'd appreciate any ideas or suggestions if you think there's a better way to pose the problem. Thanks in advance!
Using plt.imshow we can make heat maps you can read more about it here: https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.imshow.html
import numpy as np
import matplotlib.pyplot as plt
matrix = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
plt.imshow(matrix, cmap='hot', interpolation='nearest')
plt.show()
output:
My go-to is Plotly for any kind of figure
import plotly.express as px
matrix = np.reshape([random.choice([0,1]) for n in range(10000)], (100, 100))
fig = px.imshow(matrix,
color_continuous_scale=['blue','red'])
fig.show()

Scatter plot in python

I have a vector X of size 100x2 and the corresponding binary labels in a vector y ={1, -1} of length 100. I would like to plot the scattered data with s.t. I get the features on the axis and the color of the data point corresponds to a label e.g. red is -1, yellow is 1 for a given data point.
I've been looking into matplotlib and the fcn scatter however it accepts only a single feature vector and its label.
I would be grateful for any help.
You can do this easily using seaborn (or matplotlib as well). Below is the code.
I am creating a random array of size 100x2 and calling it X. I am creating a random array of 0s and 1s of size 100x1 and calling it Y
>> import numpy as np
>> X = np.random.randint(100, size=(100, 2))
>> Y = np.random.choice([0, 1], size=(100))
>> X
array([[11, 47],
[23, 2],
[91, 14],
[65, 32],
[81, 78],
....
>> Y
array([0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1,
0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0,
1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1,
0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1])
Use Seaborn scatterplot
import seaborn as sns
sns.scatterplot(x=X[:,0], y=X[:,1], hue=Y)
Output sns scatterplot

Seaborn heatmap fit annotation text to cell

I have this code that displays a confusion matrix. In each cell, first the accuracy is displayed then under it the number of correct predicted samples/total samples. Now I want to display all the text inside each cell. First cell for exemple should displays 186/208 under the accuracy.
How can I show the whole text of annotations inside the cell ? I tried to reduce the font size but it did not work.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
def cm_analysis(cm, labels, figsize=(20,15)):
cm_sum = np.sum(cm, axis=1, keepdims=True)
cm_perc = cm / cm_sum.astype(float)
annot = np.empty_like(cm).astype(str)
nrows, ncols = cm.shape
for i in range(nrows):
for j in range(ncols):
c = cm[i, j]
p = cm_perc[i, j]
if i == j:
s = cm_sum[i]
annot[i, j] = '%.2f%%\n%d/%d' % (p, c, s)
elif c == 0:
annot[i, j] = ''
else:
annot[i, j] = '%.2f%%\n%d' % (p, c)
cm = pd.DataFrame(cm, index=labels, columns=labels)
cm.index.name = 'Groundtruth labels'
cm.columns.name = 'Predicted labels'
fig, ax = plt.subplots(figsize=figsize)
ax.axhline(color='black')
g =sns.heatmap(cm, cmap="BuPu", annot_kws={"weight": "bold"}, annot=annot, fmt='', ax=ax, cbar_kws={'label': 'Number of samples'}, linewidths=0.1, linecolor='black')
g.set_xticklabels(g.get_xticklabels(), rotation = 45)
sns.set(font_scale=1.1)
plt.savefig("filename.png")
normalised_confusion_matrix = np.array(
[[186,3,0,1,2,0,3,3,7,1,2,0,0],
[5,9,1,0,3,0,0,0,0,0,0,0,1],
[0,0,49,3,0,0,0,0,1,0,0,0,6],
[1,0,6,89,0,0,0,0,1,1,1,0,1],
[3,7,0,0,50,0,0,0,6,0,1,0,0],
[1,0,0,0,0,9,0,1,0,0,0,0,0],
[3,0,1,0,0,0,54,0,0,0,3,0,0],
[2,0,0,0,0,0,2,7,0,0,0,0,0],
[3,0,0,0,2,1,2,0,53,2,4,0,0],
[0,0,0,1,0,1,0,0,1,7,0,1,0],
[1,1,0,0,1,0,1,0,3,0,52,0,0],
[1,0,0,0,0,0,0,0,1,0,0,5,0],
[0,0,11,2,0,0,0,0,0,0,0,0,26]]
)
classes = ['Assemble system','Consult sheets','Picking in front','Picking left','Put down component','Put down measuring rod','Put down screwdriver','Put down subsystem','Take component','Take measuring rod','Take screwdriver','Take subsystem','Turn sheets']
cm_analysis(cm= normalised_confusion_matrix, labels = classes)
The principal problem is creating the annot array as type str instead of object (so, annot = np.empty_like(cm).astype(object)). Having it of type str leads to strange errors, as numpy strings have some maximum length built-in. (See also this post.)
As you only use one index in cm_sum[i], it's better to not "keep the dimensions" in cm_sum = np.sum(cm, axis=1, keepdims=False) (docs).
Also, note that for a percentage, you need to multiply with 100. (The modern way to created formatted strings would use f-strings: annot[i, j] = f'{p*100:.2f}%\n{c}/{s}').
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
def cm_analysis(cm, labels, figsize=(20, 15)):
cm_sum = np.sum(cm, axis=1, keepdims=False)
cm_perc = cm / cm_sum.astype(float)
annot = np.empty_like(cm).astype(object)
nrows, ncols = cm.shape
for i in range(nrows):
for j in range(ncols):
c = cm[i, j]
p = cm_perc[i, j]
if i == j:
s = cm_sum[i]
annot[i, j] = f'{p*100:.1f}%\n{c}/{s}'
elif c == 0:
annot[i, j] = ''
else:
annot[i, j] = f'{p*100:.1f}%\n{c}'
cm = pd.DataFrame(cm, index=labels, columns=labels)
cm.index.name = 'Groundtruth labels'
cm.columns.name = 'Predicted labels'
fig, ax = plt.subplots(figsize=figsize)
ax.axhline(color='black')
g = sns.heatmap(cm, cmap="BuPu", annot_kws={"weight": "bold"}, annot=annot, fmt='', ax=ax,
cbar_kws={'label': 'Number of samples'}, linewidths=0.1, linecolor='black')
g.set_xticklabels(g.get_xticklabels(), rotation=45)
sns.set(font_scale=1.1)
plt.savefig("filename.png")
normalised_confusion_matrix = np.array(
[[186, 3, 0, 1, 2, 0, 3, 3, 7, 1, 2, 0, 0],
[5, 9, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 49, 3, 0, 0, 0, 0, 1, 0, 0, 0, 6],
[1, 0, 6, 89, 0, 0, 0, 0, 1, 1, 1, 0, 1],
[3, 7, 0, 0, 50, 0, 0, 0, 6, 0, 1, 0, 0],
[1, 0, 0, 0, 0, 9, 0, 1, 0, 0, 0, 0, 0],
[3, 0, 1, 0, 0, 0, 54, 0, 0, 0, 3, 0, 0],
[2, 0, 0, 0, 0, 0, 2, 7, 0, 0, 0, 0, 0],
[3, 0, 0, 0, 2, 1, 2, 0, 53, 2, 4, 0, 0],
[0, 0, 0, 1, 0, 1, 0, 0, 1, 7, 0, 1, 0],
[1, 1, 0, 0, 1, 0, 1, 0, 3, 0, 52, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 5, 0],
[0, 0, 11, 2, 0, 0, 0, 0, 0, 0, 0, 0, 26]]
)
classes = ['Assemble system', 'Consult sheets', 'Picking in front', 'Picking left', 'Put down component',
'Put down measuring rod', 'Put down screwdriver', 'Put down subsystem', 'Take component',
'Take measuring rod', 'Take screwdriver', 'Take subsystem', 'Turn sheets']
cm_analysis(cm=normalised_confusion_matrix, labels=classes)

How to fix hopfield library errors in python

I have some code about hopfield network. I am trying to train some letters with hebbian training and then add noise and denoise them. However, I have problem with libraries. I did a search but I cant find the right answer to my problem. Hopfieldnet library is not working and if I try to replace it I take other errors. Can u help me?
from random import randint
import numpy as np
import HopfieldNetwork
from hopfieldnet.trainers import hebbian_training
from matplotlib import pyplot as plt
# Create the training patterns
j_pattern = np.array([[1, 1, 1, 1, 1],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[1, 0, 1, 0, 0],
[1, 1, 1, 0, 0]])
a_pattern = np.array([[0, 0, 1, 0, 0],
[0, 1, 0, 1, 0],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1]])
m_pattern = np.array([[1, 0, 0, 0, 1],
[1, 1, 0, 1, 1],
[1, 0, 1, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1]])
e_pattern = np.array([[1, 1, 1, 1, 1],
[1, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[1, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 1, 1, 1, 1]])
s_pattern = np.array([[1, 1, 1, 1, 1],
[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1],
[1, 1, 1, 1, 1]])
j_pattern *= 2
j_pattern -= 1
a_pattern *= 2
a_pattern -= 1
m_pattern *= 2
m_pattern -= 1
e_pattern *= 2
e_pattern -= 1
s_pattern *= 2
s_pattern -= 1
input_patterns = np.array([j_pattern.flatten(), a_pattern.flatten(), m_pattern.flatten(), e_pattern.flatten(), s_pattern.flatten()])
# Create the neural network and train it using the training patterns
network = HopfieldNetwork(35)
hebbian_training(network, input_patterns)
# Create the test patterns by using the training patterns and adding some noise to them
# and use the neural network to denoise them
j_test = j_pattern.flatten()
for i in range(4):
p = randint(0, 34)
j_test[p] *= -1
j_result = network.run(j_test)
j_result.shape = (7, 5)
j_test.shape = (7, 5)
a_test = a_pattern.flatten()
for i in range(4):
p = randint(0, 34)
a_test[p] *= -1
a_result = network.run(a_test)
a_result.shape = (7, 5)
a_test.shape = (7, 5)
m_test = m_pattern.flatten()
for i in range(4):
p = randint(0, 34)
m_test[p] *= -1
m_result = network.run(m_test)
m_result.shape = (7, 5)
m_test.shape = (7, 5)
e_test = e_pattern.flatten()
for i in range(4):
p = randint(0, 34)
e_test[p] *= -1
e_result = network.run(e_test)
e_result.shape = (7, 5)
e_test.shape = (7, 5)
s_test = s_pattern.flatten()
for i in range(4):
p = randint(0, 34)
s_test[p] *= -1
s_result = network.run(s_test)
s_result.shape = (7, 5)
s_test.shape = (7, 5)
# Show the results
plt.subplot(3, 2, 1)
plt.imshow(j_test, interpolation="nearest")
plt.subplot(3, 2, 2)
plt.imshow(j_result, interpolation="nearest")
plt.subplot(3, 2, 3)
plt.imshow(a_test, interpolation="nearest")
plt.subplot(3, 2, 4)
plt.imshow(a_result, interpolation="nearest")
plt.subplot(3, 2, 5)
plt.imshow(m_test, interpolation="nearest")
plt.subplot(3, 2, 6)
plt.imshow(m_result, interpolation="nearest")
plt.subplot(3, 2, 7)
plt.imshow(e_test, interpolation="nearest")
plt.subplot(3, 2, 8)
plt.imshow(e_result, interpolation="nearest")
plt.subplot(3, 2, 9)
plt.imshow(s_test, interpolation="nearest")
plt.subplot(3, 2, 10)
plt.imshow(s_result, interpolation="nearest")
plt.show()
The error:
"C:/Users/chriss/PycharmProjects/untitled3/hopfield.py", line 3, in <module> import HopfieldNetwork ModuleNotFoundError: No module named 'HopfieldNetwork'
Not sure if it is actual solution to the problem. I cannot reproduce the error. Code works for me after 3 slight modifications.
(1) Imports
from random import randint
import numpy as np
from hopfieldnet.net import HopfieldNetwork # modified import
from hopfieldnet.trainers import hebbian_training
from matplotlib import pyplot as plt
(2) Drawing
plt.subplot(3, 4, ...) # 3 * 4 = 12 places for 10 plots
(3) hopfieldnet module -> net.py -> class HopfieldNetwork -> method run
update_list = list(range(self._num_inputs)) # list(range(...)) instead of just range(...)

Python matlibplot: visualizing a matrix of integers (-1, 0 or 1) with circles (same radius, different color)

I have a square matrix filled by -1, 0 or 1. I would like to visualize this matrix with spheres or circles of the same radius. Radius, indeed is not important at all. Those circles though, must have a different colour according to the number of the matrix cell.
For example:
10 x 10 matrix -> 100 circles on a plane, 10 rows x 10 columns
Color of circle in position (2,9) depending on number of matrix in position (2,9).
Thank you!
People I know told me to use matlibplot, but I am new to Python and
I have many issues!
This is what I did up to now:
{`
import numpy as np
#from implementations import *
#from config import *
import matplotlib.pyplot as plt
A = np.array([
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 2, -1, -1,-1, 2, 1, 0, 0],
[0, 1, 2, -1, -1,-1, 2, 1, 0, 0],
[0, 1, 2, -1, -1,-1, 2, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
])
rows=len(A) # finding number rows of lattice, so no need to worry about it!
columns=len(A[0]) # finding number columns of lattice, so no need to worry about it!
fig, ax = plt.subplots()
for i in range(rows):
for j in range(columns):
if A[i][j]==-1:
circle1 = plt.Circle((i*4, j*4), 2, color='blue')
fig = plt.gcf()
ax = fig.gca()
ax.add_artist(circle1)
if A[i][j]== 1:
circle2 = plt.Circle((i*4, j*4), 2, color='yellow')
fig = plt.gcf()
ax = fig.gca()
ax.add_artist(circle2)
`}
Here is the matplotlib code that uses scatter matrix:
# Imports
import matplotlib.pyplot as plt
from itertools import chain
# Create plot
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
# Here is our matrix. Note, that it is expected to be rectangular!
matrix = [
[0, 1, 0,1],
[-1,1, 0,0],
[1,-1,-1,1],
]
# Get X-length
X = len(matrix[0])
# Get Y-length
Y = len(matrix)
# Construct grids for scatter
x_grid = list(range(X)) * Y # 1,2,3,4,1,2,3,4...
y_grid = [y for y in range(Y) for _ in range(X)] # 1,1,1,1,2,2,2,2...
# Flatten the matrix because ax.scatter uses flat arrays
matrix_grid = list(chain(*matrix))
plt.scatter(
x_grid, # X-grid array of coordinates
y_grid, # Y-grid array of coordinates
c=matrix_grid, # Our flatten matrix of -1/0/1s
cmap='gist_rainbow' # Color map - defines colors
)
You can directly use a scatter as follows:
import numpy as np
import matplotlib.pyplot as plt
A = np.array([
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 2, -1, -1,-1, 2, 1, 0, 0],
[0, 1, 2, -1, -1,-1, 2, 1, 0, 0],
[0, 1, 2, -1, -1,-1, 2, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
])
X,Y = np.meshgrid(np.arange(A.shape[1]), np.arange(A.shape[0]))
plt.scatter(X.flatten(), Y.flatten(), c=A.flatten())
plt.show()

Categories