How to have 2 different ticklabels in a confusion matrix? - python

I have plotted the Confusion Matrix that you see below.
I want to change the labels.
Instead of s1 -> s37. I want: s1 -> s21, I1 -> I16
import itertools
def plot_confusion_matrix(cm, title='Confusion matrix RF', cmap=plt.cm.viridis):
plt.imshow(cm, interpolation='nearest', cmap=cmap) #Display an image on the axes
plt.title(title)
plt.colorbar() #the vertical bar at the right side
#tick_marks = np.arange(len(np.unique(y_oos))) #has the length of the # of classes (array)
tick_marks = np.arange(37) #I KNOW IT IS HERE!!!
plt.xticks(tick_marks, rotation=90) #to Rotate the names
ax = plt.gca()
ax.set_xticklabels(['s'+lab for lab in (ax.get_xticks()+1).astype(str)]) # AND ALSO HERE!!!
plt.yticks(tick_marks)
ax.set_yticklabels(['s'+lab for lab in (ax.get_yticks()+1).astype(str)])
plt.tight_layout() #
plt.ylabel('True label')
plt.xlabel('Predicted label')

I passed a custom list; as mentionned above.
import itertools
def plot_confusion_matrix(cm, title='Confusion matrix RF', cmap=plt.cm.viridis):
plt.imshow(cm, interpolation='nearest', cmap=cmap)
plt.title(title)
plt.colorbar() #the vertical bar at the right side
tick_marks = np.arange(37) #21 + 16 = 37
#THIS IS THE CUSTOM LIST!
labels = ['s1','s2','s3','s4','s5','s6','s7','s8','s9','s10','s11','s12','s13','s14','s15','s16','s17','s18','s19','s20','s21','i1','i2','i3','i4','i5','i6','i7','i8','i9','i10','i11','i12','i13','i14','i15','i16']
plt.xticks(tick_marks, rotation=90) #to totate the names
ax = plt.gca()
ax.set_xticklabels(labels)
plt.yticks(tick_marks)
ax.set_yticklabels(labels)
plt.tight_layout() #
plt.ylabel('True label')
plt.xlabel('Predicted label')

Related

Aligning rotated xticklabels and ylabels with their respective xticks and yticks

Here is the output of the code :
array = [[64,7,5],
[9,195,1],
[6,17,2]]
df_cm = pd.DataFrame(array, range(3), range(3))
sn.set(font_scale=1.4) # for l)abel size
sn.heatmap(df_cm, annot=True, annot_kws={"size": 16}, cmap='Blues', fmt='g') # font size
class_names = ['dog','cat','bear']
plt.gca().xaxis.tick_top()
plt.gca().xaxis.set_label_position('top')
tick_marks = np.arange(len(class_names))
plt.xticks(tick_marks, class_names, rotation=45, rotation_mode='anchor')
plt.yticks(tick_marks, class_names, rotation='horizontal')# rotation='horizontal', ha='right', rotation_mode='anchor'
plt.tight_layout()
plt.ylabel('True label',size=14)
plt.xlabel('Predicted label',size=14)
plt.show()
I would like to align labels of x and y with center position, So please how can I change the above
With tick_marks = np.arange(len(class_names)) you're setting new tick marks. Just get the existing ones with ax.get_xticks()/ax.get_yticks():
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sn
array = [[64,7,5],
[9,195,1],
[6,17,2]]
df_cm = pd.DataFrame(array, range(3), range(3))
sn.set(font_scale=1.4) # for l)abel size
fig, ax = plt.subplots()
sn.heatmap(df_cm, annot_kws={"size": 16}, cmap='Blues', fmt='g') # font size
class_names = ['dog','cat','bear']
plt.gca().xaxis.tick_top()
plt.gca().xaxis.set_label_position('top')
plt.xticks(ax.get_xticks(), class_names, rotation=45, rotation_mode='anchor')
plt.yticks(ax.get_yticks(), class_names, rotation='horizontal')# rotation='horizontal', ha='right', rotation_mode='anchor'
plt.tight_layout()
plt.ylabel('True label',size=14)
plt.xlabel('Predicted label',size=14)
plt.show()
Output:
Edit: you'll achieve the same result by replacing your plt.xticks(...) and plt.yticks(...) with the following:
plt.gca().set_xticklabels(class_names, rotation=45, rotation_mode='anchor')
plt.gca().set_yticklabels(class_names, rotation='horizontal')

Confusion Matrix font size

I have a Confusion Matrix with really small sized numbers but I can't find a way to change them.
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, rf_predictions)
ax = plt.subplot()
sns.set(font_scale=3.0) #edited as suggested
sns.heatmap(cm, annot=True, ax=ax, cmap="Blues", fmt="g"); # annot=True to annotate cells
# labels, title and ticks
ax.set_xlabel('Predicted labels');
ax.set_ylabel('Observed labels');
ax.set_title('Confusion Matrix');
ax.xaxis.set_ticklabels(['False', 'True']);
ax.yaxis.set_ticklabels(['Flase', 'True']);
plt.show()
thats the code I am using and the pic I get looks like:
I would not mind changing the numbers of the classification by hand but I dont really want to do it for the labels aswell.
EDIT: Figures are bigger now but the labels stay very small
Cheers
Use sns.set to change the font size of the heatmap values. You can specify the font size of the labels and the title as a dictionary in ax.set_xlabel, ax.set_ylabel and ax.set_title, and the font size of the tick labels with ax.tick_params.
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, rf_predictions)
ax = plt.subplot()
sns.set(font_scale=3.0) # Adjust to fit
sns.heatmap(cm, annot=True, ax=ax, cmap="Blues", fmt="g");
# Labels, title and ticks
label_font = {'size':'18'} # Adjust to fit
ax.set_xlabel('Predicted labels', fontdict=label_font);
ax.set_ylabel('Observed labels', fontdict=label_font);
title_font = {'size':'21'} # Adjust to fit
ax.set_title('Confusion Matrix', fontdict=title_font);
ax.tick_params(axis='both', which='major', labelsize=10) # Adjust to fit
ax.xaxis.set_ticklabels(['False', 'True']);
ax.yaxis.set_ticklabels(['False', 'True']);
plt.show()
Use rcParams to change all text in the plot:
fig, ax = plt.subplots(figsize=(10,10))
plt.rcParams.update({'font.size': 16})
disp = plot_confusion_matrix(clf, Xt, Yt,
display_labels=classes,
cmap=plt.cm.Blues,
normalize=normalize,
ax=ax)
Found it
import itertools
import matplotlib.pyplot as plt
def plot_confusion_matrix(cm,classes,normalize=False,title='Confusion
matrix',cmap=plt.cm.Blues):
plt.figure(figsize=(15,10))
plt.imshow(cm,interpolation='nearest',cmap=cmap)
plt.title(title)
plt.colorbar()
tick_marks=np.arange(len(classes))
plt.xticks(tick_marks,classes,rotation=45,fontsize=15)
plt.yticks(tick_marks,classes,fontsize=15,rotation=90)
if normalize:
cm=cm.astype('float')/cm.sum(axis=1)[:,np.newaxis]
cm=np.around(cm,decimals=2)
cm[np.isnan(cm)]=0.0
print('Normalized confusion matrix')
else:
print('Confusion matrix, without normalization')
thresh=cm.max()/2
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j, i, cm[i, j],
horizontalalignment="center",fontsize=15,
color="white" if cm[i, j] > thresh else "black")
plt.tight_layout()
plt.ylabel('True label',fontsize=20)
plt.xlabel('Predicted label',fontsize=20)
The code changed as such

How do I animate this graph so that the dot moves and the green line plots over a different range for each element in loop?

I am trying to make this animated so that the dot and the green line move due to the for loop. This code displays 3 different graphs one below the other. The middle graph has no animation section.
x =lag_range
count = 0
plt.ion()
fig, ax = plt.subplots()
for b in x:
plt.subplot(311)
plt.plot(x,pear_corr, color='b', linewidth=1.5, label ='Pearson')
plt.plot(x,spear_corr, color ='r', linewidth=1.5, label='Spearman')
plt.plot(x[count],pear_corr[count],'yo')
plt.legend()
axes = plt.gca()
plt.ylabel('Correlation coefficients')
plt.xlabel('Lag times /days')
axes.set_xlim([min(lag_list),last])
axes.set_ylim(-1,1)
plt.subplot(312)
plt.plot(x,pear_p_values, color='b', linewidth=1.5)
plt.plot(x,spear_p_values, color ='r', linewidth=1.5)
axes = plt.gca()
plt.ylabel('P values')
plt.xlabel('Lag times /days')
axes.set_xlim([min(lag_list),last])
plt.subplot(313)
ax1 = plt.subplot(313)
x_for_p = range(len(x_prices))
ax1.plot(x_for_p, x_prices, color ='grey', linewidth=1.5)
ax1.set_ylabel('Share price', color ='grey')
ax1.tick_params('y', colors='grey')
ax1.set_xlabel('Days')
axes = plt.gca()
axes.set_xlim([min(lag_list),(2*last)])
ax2 = ax1.twinx()
x_for_den = range(b,(b+len(x_prices)))
ax2.plot(x_for_den, y_planes, color='g', linewidth=1.5)
ax2.set_ylabel('Plane density', color='g')
ax2.tick_params('y', colors='g')
count += 1
plt.pause(2)
plt.draw()
cross_corr2_vis(prices, density_p3)
If you could share a working code or just definitions of variables pear_corr, spear_corr, etc., the following code might have not resulted in this simple animation:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
N_points = 1000
x = np.linspace(0,2.*np.pi,N_points)
y = np.sin(x)
fig, ax = plt.subplots()
ax.set_xlim([0,2.*np.pi])
ax.set_ylim([-1,1])
line, = ax.plot( [],[], lw=2, color='g')
sctr = ax.scatter([],[], s=100, color='r')
def animate(i):
line.set_ydata(y[:i+1]) # update
line.set_xdata(x[:i+1])
sctr.set_offsets((x[i],y[i]))
return line,sctr
ani = animation.FuncAnimation(fig, animate, N_points, interval=5, blit=True)
plt.show()

How to plot confusion matrix correctly

Does anyone know how I can plot confusion matrix for 100 class labels? I did these line of codes but I ended up having a confusion matrix attached. The code is working fine for less class numbers like 5 but as the number of classes is 100, there in no clear confusion matrix.
y_pred = model.predict(X_test)
confmat = confusion_matrix(y_true=y_test, y_pred=y_pred)
print(confmat)
fig, ax = plt.subplots(figsize=(5, 5))
ax.matshow(confmat, cmap=plt.cm.Blues, alpha=0.3)
for i in range(confmat.shape[0]):
for j in range(confmat.shape[1]):
ax.text(x=j, y=i, s=confmat[i, j], va='center', ha='center')
plt.xlabel('predicted label')
plt.ylabel('true label')
plt.show()

Partial coloring of text in 3D plot Matplotlib

Is it possible to change the color of a text in 3D plot. My question is similar to this Question Partial coloring of text in matplotlib but instead of 2d plot I am using 3D plot.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import transforms
fig = plt.figure()
ax = Axes3D(fig)
x =1
y =2
z =3
ax.set_xlim3d(0,5)
ax.set_ylim3d(0,5)
ax.set_zlim3d(0,5)
ax.set_xticks(range(5))
ax.set_yticks(range(5))
ax.set_zticks(range(5))
t=ax.transData
ax.scatter([x], [y], [z], c='r', marker='*', s=500)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
ls="Data Point".split()
lc=['red','orange']
x=0.5
y=0.5
z=0.5
for s,c in zip(ls,lc):
try:
text = ax.text(x,y,z," "+s+" ",color=c, transform=t,size=50)
text.draw(fig.canvas.get_renderer())
ex = text.get_window_extent()
t = transforms.offset_copy(text._transform, y=ex.height,x=ex.width, units='dots')
except:
print "error"
plt.show()

Categories