Python Matplotlib discrete note

Anh-Thi Dinh

Import library

1import matplotlib.pyplot as plt
2import numpy as np

Generate colors based on list

We wanna generate a list of colors automatically based on the elements in some list (the idea from popai),
1def get_colors(list_vals, list_colors=["#fb4747", "#315ace", "#b5f6e5", "#FFB347"]):
2    dict_colors = polylinear_gradient(list_colors, n=len(list_vals))
3    dict_colors_ok = {}
4    for i, val in enumerate(list_vals):
5        dict_colors_ok[val] = dict_colors['hex'][i]
6
7    return dict_colors_ok

Axes

Axes' options,
1# Hide the axis
2plt.axis('off')
3# and 'on' to display it again
1# Set the limit
2plt.xlim(0, 3.5)
3plt.ylim(0, 3.5)
1# Axes' label
2plt.xlabel('students', fontsize=14)
3plt.ylabel('mark')
1# axes' tick size & rotation
2plt.xticks(fontsize=14, rotation=90)
3plt.yticks(fontsize=14, rotation=90)
1# range of ticks
2plt.xticks(np.arange(0., 1., step=0.01))
3plt.yticks(np.arange(0., 1., step=0.01))
Set equal 2 axes (ref),
1matplotlib.axes.Axes.set_aspect('equal')
2# get the current axes and apply the function
3plt.gca().set_aspect()

Plots

Check the official doc for more information.
1# default for all
2matplotlib.rcParams['figure.figsize'] = (20,5)
1plt.plot(X, y, 'ro') # red and 'o' points
1# set figure size
2plt.figure(figsize=(20, 5))
3plt.figure(figsize=(20, 5), dpi= 60)
1# rotate z label
2plt.xticks(rotation=90, fontsize=10)
1# linestyle and marker
2plt.plot(marker='.', ls='') # scatter plot
3plt.plot(X, '.', markersize=15, linewidth=2)

Plot directly with dataframe,

👉 Check more in official doc.
1df.plot(figsize=(20, 5))
2df.plot(fontsize=12)
1# different types
2df.plot(style='.')
3df.plot(style=['r.', 'bx']) # 2 features
1# add x,y labels
2df.plot(kind='bar)
3plt.xlabel('features', fontsize=14)
4plt.ylabel('% of nans', fontsize=14)
1# rotate x ticks
2df.plot(kind='bar', rot=90)

Legend

1# from the plots
2plt.plot(x, np.sin(x), '-b', label='Sine')
3plt.plot(x, np.cos(x), '--r', label='Cosine')
4plt.legend(fontsize=13)
1# custom: independent from the plots
2from matplotlib.lines import Line2D
3plt.legend([Line2D([0], [0], color='b'), Line2D([0], [0], color='r')], ['blue', 'red'])

Legend from list of colors

Suppose we have a list of group with different colors. We wanna make legends for them,
1# generate auto the colors based on list lst_clusters (see previous section)
2dict_colors = get_colors(lst_clusters)
3
4plt.legend(
5    [Line2D([0], [0], color=dict_colors[key]) for key in dict_colors],
6    dict_colors.keys(),
7    loc='lower center',
8    ncol=6,
9    bbox_to_anchor=(.5, 1.),
10    prop={'size': 15}
11)

imshow

Plot from a list of true/false (ref to an example of Bernoulli distribution)
1image = # np.array(4, 4) of random True/False
2plt.imshow(image, cmap='gray') # plot
3plt.show()

Subplot

For example, we wanna create a 4x4 plots (ref),
1plt.figure(figsize=(12, 10), dpi= 60)
2for i in range(4):
3    pos = i+1
4    plt.subplot(2,2,pos)
5    plt.plot(X[i])
6    plt.title('title_'+str(pos), fontsize=18)
Using ax
1size = len(list_features)
2f, axs = plt.subplots(int((size+1)/2), 2, figsize=(15,15/5*int(size/2 + 1/2)))
3for ax, feat in zip(axs.ravel(), list_features):
4    df_feat = df[feat]
5    for idt, df_id in df_feat.groupby('batch_id'):
6        ax.plot(x, y, color='royalblue', alpha=0.5)
7        ax.set_title('plot_'+feat)
8plt.show()

Fill between range

1plt.fill_between(df.index, df["yhat_lower"], df["yhat_upper"], color='#0072B2', alpha=0.2)

Plot a photo (imshow)

With grayscale and misc

1from scipy import misc
2
3img = misc.face(gray=True)
4plt.imshow(img, cmap='gray', vmin=0, vmax=255)
5plt.show()

With grayscale and custom file

1import numpy as np
2import matplotlib.pyplot as plt
3from PIL import Image
4
5fname = 'image.png'
6image = Image.open(fname).convert("L")
7# If you have an L mode image, that means it is a single channel image - normally
8#   interpreted as greyscale. The L means that is just stores the Luminance.
9#   It is very compact, but only stores a greyscale, not colour.
10
11arr = np.asarray(image)
12plt.imshow(arr, cmap='gray', vmin=0, vmax=255)
13plt.show()
14print(arr.shape)
1# ERR: Clipping input data to the valid range for
2#   imshow with RGB data ([0..1] for floats or [0..255] for integers)
3plt.imshow(img.astype('uint8'))

Save figure to file

Using plt.savefig()

To be sure that plt.savefig() (ref) comes before plt.show(). In the case you wanna use any time you want, just call plt.gcf() to "get current figure" first. For example, (ref)
1fig1 = plt.gcf() # get the current figure
2plt.show() # show the plot
3fig1.savefig('test.png', dpi=100
Remark: There are the axes inside the exported photo (all are printed on notebook)!!

Using imageio

They export only the photo.
1import imageio
2# img = misc.face(gray=True)
3# or
4# img = np.asarray(Image.open('abc.jpg').convert("L"))
5imageio.imwrite('filename.jpg', img) # save the file
1# ERR: Lossy conversion from float64 to uint8. Range […,…].
2#   Convert image to uint8 prior to saving to suppress this warning
3imageio.imwrite('filename.jpg', img.astype(np.uint8))