Vi. Change

Time Series Plot

A time series diagram is used to show how a given measure changes over time. Here you can see how air passenger traffic changed between 1949 and 1969.

# Import Data
df = pd.read_csv('https://github.com/selva86/datasets/raw/master/AirPassengers.csv')

# Draw Plot
plt.figure(figsize=(16.10), dpi= 80)
plt.plot('date'.'traffic', data=df, color='tab:red')

# Decoration
plt.ylim(50.750)
xtick_location = df.index.tolist()[::12]
xtick_labels = [x[-4:] for x in df.date.tolist()[::12]]
plt.xticks(ticks=xtick_location, labels=xtick_labels, rotation=0, fontsize=12, horizontalalignment='center', alpha=7.)
plt.yticks(fontsize=12, alpha=7.)
plt.title("Air Passengers Traffic (1949 - 1969)", fontsize=22)
plt.grid(axis='both', alpha=3.)

# Remove borders
plt.gca().spines["top"].set_alpha(0.0)    
plt.gca().spines["bottom"].set_alpha(0.3)
plt.gca().spines["right"].set_alpha(0.0)    
plt.gca().spines["left"].set_alpha(0.3)   
plt.show()
Copy the code

36 Time Series with Peaks and Troughs

The time series below plots all peaks and troughs and annotates the occurrence of selected particular events.

# Import Data
df = pd.read_csv('https://github.com/selva86/datasets/raw/master/AirPassengers.csv')

# Get the Peaks and Troughs
data = df['traffic'].values
doublediff = np.diff(np.sign(np.diff(data)))
peak_locations = np.where(doublediff == -2) [0] + 1

doublediff2 = np.diff(np.sign(np.diff(-1*data)))
trough_locations = np.where(doublediff2 == -2) [0] + 1

# Draw Plot
plt.figure(figsize=(16.10), dpi= 80)
plt.plot('date'.'traffic', data=df, color='tab:blue', label='Air Traffic')
plt.scatter(df.date[peak_locations], df.traffic[peak_locations], marker=mpl.markers.CARETUPBASE, color='tab:green', s=100, label='Peaks')
plt.scatter(df.date[trough_locations], df.traffic[trough_locations], marker=mpl.markers.CARETDOWNBASE, color='tab:red', s=100, label='Troughs')

# Annotate
for t, p in zip(trough_locations[1: :5], peak_locations[::3]):
    plt.text(df.date[p], df.traffic[p]+15, df.date[p], horizontalalignment='center', color='darkgreen')
    plt.text(df.date[t], df.traffic[t]-35, df.date[t], horizontalalignment='center', color='darkred')

# Decoration
plt.ylim(50.750)
xtick_location = df.index.tolist()[::6]
xtick_labels = df.date.tolist()[::6]
plt.xticks(ticks=xtick_location, labels=xtick_labels, rotation=90, fontsize=12, alpha=7.)
plt.title("Peak and Troughs of Air Passengers Traffic (1949 - 1969)", fontsize=22)
plt.yticks(fontsize=12, alpha=7.)

# Lighten borders
plt.gca().spines["top"].set_alpha(. 0)
plt.gca().spines["bottom"].set_alpha(3.)
plt.gca().spines["right"].set_alpha(. 0)
plt.gca().spines["left"].set_alpha(3.)

plt.legend(loc='upper left')
plt.grid(axis='y', alpha=3.)
plt.show()
Copy the code

37 Autocorrelation (ACF) and Partial Autocorrelation (PACF) plots

Autocorrelation diagram (ACF diagram) shows the correlation between time series and their own lag. Each vertical line (on autocorrelation plots) represents the correlation between the series and the hysteresis 0. The blue shaded areas in the figure are significant levels. Those lags above the blue line are significant lags.

For flight attendant travelers, we see up to 14 lags across the blue line, so it’s very important. This means that air passenger traffic 14 years ago has an impact on today’s traffic.

PACF, on the other hand, shows the autocorrelation between any given lag (time series) and the current sequence, but removes the delayed contribution.

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# Import Data
df = pd.read_csv('https://github.com/selva86/datasets/raw/master/AirPassengers.csv')

# Draw Plot
fig, (ax1, ax2) = plt.subplots(1.2,figsize=(16.6), dpi= 80)
plot_acf(df.traffic.tolist(), ax=ax1, lags=50)
plot_pacf(df.traffic.tolist(), ax=ax2, lags=20)

# Decorate
# lighten the borders
ax1.spines["top"].set_alpha(3.); ax2.spines["top"].set_alpha(3.)
ax1.spines["bottom"].set_alpha(3.); ax2.spines["bottom"].set_alpha(3.)
ax1.spines["right"].set_alpha(3.); ax2.spines["right"].set_alpha(3.)
ax1.spines["left"].set_alpha(3.); ax2.spines["left"].set_alpha(3.)

# font size of tick labels
ax1.tick_params(axis='both', labelsize=12)
ax2.tick_params(axis='both', labelsize=12)
plt.show()
Copy the code

38 Cross Correlation plot

The cross correlation diagram shows the lag between two time series.

import statsmodels.tsa.stattools as stattools

# Import Data
df = pd.read_csv('https://github.com/selva86/datasets/raw/master/mortality.csv')
x = df['mdeaths']
y = df['fdeaths']

# Compute Cross Correlations
ccs = stattools.ccf(x, y)[:100]
nlags = len(ccs)

# Compute the Significance level
# ref: https://stats.stackexchange.com/questions/3115/cross-correlation-significance-in-r/3128#3128
conf_level = 2 / np.sqrt(nlags)

# Draw Plot
plt.figure(figsize=(12.7), dpi= 80)

plt.hlines(0, xmin=0, xmax=100, color='gray')  # 0 axis
plt.hlines(conf_level, xmin=0, xmax=100, color='gray')
plt.hlines(-conf_level, xmin=0, xmax=100, color='gray')

plt.bar(x=np.arange(len(ccs)), height=ccs, width=3.)

# Decoration
plt.title('$Cross\; Correlation\; Plot:\; mdeaths\; vs\; fdeaths$', fontsize=22)
plt.xlim(0.len(ccs))
plt.show()
Copy the code

Time Series Decomposition Plot

The time series decomposition diagram shows the time series decomposition into trend, season and residual components.

from statsmodels.tsa.seasonal import seasonal_decompose
from dateutil.parser import parse

# Import Data
df = pd.read_csv('https://github.com/selva86/datasets/raw/master/AirPassengers.csv')
dates = pd.DatetimeIndex([parse(d).strftime('%Y-%m-01') for d in df['date']])
df.set_index(dates, inplace=True)

# Decompose
result = seasonal_decompose(df['traffic'], model='multiplicative')

# Plot
plt.rcParams.update({'figure.figsize': (10.10)})
result.plot().suptitle('Time Series Decomposition of Air Passengers')
plt.show()
Copy the code

Multiple Time Series

You can plot multiple time series, measuring the same values on the same chart, as shown below.

# Import Data
df = pd.read_csv('https://github.com/selva86/datasets/raw/master/mortality.csv')

# Define the upper limit, lower limit, interval of Y axis and colors
y_LL = 100
y_UL = int(df.iloc[:, 1:].max().max(*)1.1)
y_interval = 400
mycolors = ['tab:red'.'tab:blue'.'tab:green'.'tab:orange']    

# Draw Plot and Annotate
fig, ax = plt.subplots(1.1,figsize=(16.9), dpi= 80)    

columns = df.columns[1:]  
for i, column in enumerate(columns):
    # Error here, Python data path remarks
    # Visit liyangbit.com to see the full article
    plt.plot(df.date.values, df[column].values, lw=1.5, color=mycolors[i])    
    plt.text(df.shape[0] +1, df[column].values[-1], column, fontsize=14, color=mycolors[i])

# Draw Tick lines  
for y in range(y_LL, y_UL, y_interval):    
    plt.hlines(y, xmin=0, xmax=71, colors='black', alpha=0.3, linestyles="--", lw=0.5)

# Decorations    
plt.tick_params(axis="both", which="both", bottom=False, top=False,    
                labelbottom=True, left=False, right=False, labelleft=True)        

# Lighten borders
plt.gca().spines["top"].set_alpha(3.)
plt.gca().spines["bottom"].set_alpha(3.)
plt.gca().spines["right"].set_alpha(3.)
plt.gca().spines["left"].set_alpha(3.)

plt.title('Number of Deaths from Lung Diseases in the UK (1974-1979)', fontsize=22)
plt.yticks(range(y_LL, y_UL, y_interval), [str(y) for y in range(y_LL, y_UL, y_interval)], fontsize=12)    
plt.xticks(range(0, df.shape[0].12), df.date.values[::12], horizontalalignment='left', fontsize=12)    
plt.ylim(y_LL, y_UL)    
plt.xlim(-2.80)    
plt.show()
Copy the code

41 Plotting with different scales using secondary Y axis

If you want to display two time series measuring two different quantities at the same point in time, you can draw a second series on the auxiliary Y-axis to the right.

# Import Data
df = pd.read_csv("https://github.com/selva86/datasets/raw/master/economics.csv")

x = df['date']
y1 = df['psavert']
y2 = df['unemploy']

# Plot Line1 (Left Y Axis)
fig, ax1 = plt.subplots(1.1,figsize=(16.9), dpi= 80)
ax1.plot(x, y1, color='tab:red')

# Plot Line2 (Right Y Axis)
ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis
ax2.plot(x, y2, color='tab:blue')

# Decorations
# ax1 (left Y axis)
ax1.set_xlabel('Year', fontsize=20)
ax1.tick_params(axis='x', rotation=0, labelsize=12)
ax1.set_ylabel('Personal Savings Rate', color='tab:red', fontsize=20)
ax1.tick_params(axis='y', rotation=0, labelcolor='tab:red' )
ax1.grid(alpha=4.)

# ax2 (right Y axis)
ax2.set_ylabel("# Unemployed (1000's)", color='tab:blue', fontsize=20)
ax2.tick_params(axis='y', labelcolor='tab:blue')
ax2.set_xticks(np.arange(0.len(x), 60))
ax2.set_xticklabels(x[::60], rotation=90, fontdict={'fontsize':10})
ax2.set_title("Personal Savings Rate vs Unemployed: Plotting in Secondary Y Axis", fontsize=22)
fig.tight_layout()
plt.show()
Copy the code

42 Time Series with Error Bands

If you have a time series data set with multiple observations per time point (date/timestamp), you can build time series with error bands. You can see some examples below based on orders at different times of the day. Another example is the number of orders that keep arriving for 45 days.

In this method, the average order quantity is represented by a white line. And you compute the 95% confidence interval and plot it around the mean.

from scipy.stats import sem

# Import Data
df = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/user_orders_hourofday.csv")
df_mean = df.groupby('order_hour_of_day').quantity.mean()
df_se = df.groupby('order_hour_of_day').quantity.apply(sem).mul(1.96)

# Plot
plt.figure(figsize=(16.10), dpi= 80)
plt.ylabel("# Orders", fontsize=16)  
x = df_mean.index
plt.plot(x, df_mean, color="white", lw=2)
plt.fill_between(x, df_mean - df_se, df_mean + df_se, color="#3F5D7D")  

# Decorations
# Lighten borders
plt.gca().spines["top"].set_alpha(0)
plt.gca().spines["bottom"].set_alpha(1)
plt.gca().spines["right"].set_alpha(0)
plt.gca().spines["left"].set_alpha(1)
plt.xticks(x[::2], [str(d) for d in x[::2]] , fontsize=12)
plt.title("User Orders by Hour of Day (95% confidence)", fontsize=22)
plt.xlabel("Hour of Day")

s, e = plt.gca().get_xlim()
plt.xlim(s, e)

# Draw Horizontal Tick lines  
for y in range(8.20.2):    
    plt.hlines(y, xmin=s, xmax=e, colors='black', alpha=0.5, linestyles="--", lw=0.5)

plt.show()
Copy the code

# "Data Source: https://www.kaggle.com/olistbr/brazilian-ecommerce#olist_orders_dataset.csv"
from dateutil.parser import parse
from scipy.stats import sem

# Import Data
df_raw = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/orders_45d.csv',
                     parse_dates=['purchase_time'.'purchase_date'])

# Prepare Data: Daily Mean and SE Bands
df_mean = df_raw.groupby('purchase_date').quantity.mean()
df_se = df_raw.groupby('purchase_date').quantity.apply(sem).mul(1.96)

# Plot
plt.figure(figsize=(16.10), dpi= 80)
plt.ylabel("# Daily Orders", fontsize=16)  
x = [d.date().strftime('%Y-%m-%d') for d in df_mean.index]
plt.plot(x, df_mean, color="white", lw=2)
plt.fill_between(x, df_mean - df_se, df_mean + df_se, color="#3F5D7D")  

# Decorations
# Lighten borders
plt.gca().spines["top"].set_alpha(0)
plt.gca().spines["bottom"].set_alpha(1)
plt.gca().spines["right"].set_alpha(0)
plt.gca().spines["left"].set_alpha(1)
plt.xticks(x[::6], [str(d) for d in x[::6]] , fontsize=12)
plt.title("Daily Order Quantity of Brazilian Retail with Error Bands (95% confidence)", fontsize=20)

# Axis limits
s, e = plt.gca().get_xlim()
plt.xlim(s, e-2)
plt.ylim(4.10)

# Draw Horizontal Tick lines  
for y in range(5.10.1):    
    plt.hlines(y, xmin=s, xmax=e, colors='black', alpha=0.5, linestyles="--", lw=0.5)

plt.show()
Copy the code

43 Stacked Area Chart

The accumulative area map can intuitively show the contribution degree of multiple time series, so it is easy to compare with each other.

# Import Data
df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/nightvisitors.csv')

# Decide Colors
mycolors = ['tab:red'.'tab:blue'.'tab:green'.'tab:orange'.'tab:brown'.'tab:grey'.'tab:pink'.'tab:olive']      

# Draw Plot and Annotate
fig, ax = plt.subplots(1.1,figsize=(16.9), dpi= 80)
columns = df.columns[1:]
labs = columns.values.tolist()

# Prepare data
x  = df['yearmon'].values.tolist()
y0 = df[columns[0]].values.tolist()
y1 = df[columns[1]].values.tolist()
y2 = df[columns[2]].values.tolist()
y3 = df[columns[3]].values.tolist()
y4 = df[columns[4]].values.tolist()
y5 = df[columns[5]].values.tolist()
y6 = df[columns[6]].values.tolist()
y7 = df[columns[7]].values.tolist()
y = np.vstack([y0, y2, y4, y6, y7, y5, y1, y3])

# Plot for each column
labs = columns.values.tolist()
ax = plt.gca()
ax.stackplot(x, y, labels=labs, colors=mycolors, alpha=0.8)

# Decorations
ax.set_title('Night Visitors in Australian Regions', fontsize=18)
ax.set(ylim=[0.100000])
ax.legend(fontsize=10, ncol=4)
plt.xticks(x[::5], fontsize=10, horizontalalignment='center')
plt.yticks(np.arange(10000.100000.20000), fontsize=10)
plt.xlim(x[0], x[-1])

# Lighten borders
plt.gca().spines["top"].set_alpha(0)
plt.gca().spines["bottom"].set_alpha(3.)
plt.gca().spines["right"].set_alpha(0)
plt.gca().spines["left"].set_alpha(3.)

plt.show()
Copy the code

44 Area Chart UnStacked

Unpiled area maps are used to visualize the progress (ups and downs) of two or more series relative to each other. In the chart below, you can clearly see that the personal savings rate declines as the median duration of unemployment increases. The chart of unaccumulated area shows this phenomenon well.

# Import Data
df = pd.read_csv("https://github.com/selva86/datasets/raw/master/economics.csv")

# Prepare Data
x = df['date'].values.tolist()
y1 = df['psavert'].values.tolist()
y2 = df['uempmed'].values.tolist()
mycolors = ['tab:red'.'tab:blue'.'tab:green'.'tab:orange'.'tab:brown'.'tab:grey'.'tab:pink'.'tab:olive']      
columns = ['psavert'.'uempmed']

# Draw Plot
fig, ax = plt.subplots(1.1, figsize=(16.9), dpi= 80)
ax.fill_between(x, y1=y1, y2=0, label=columns[1], alpha=0.5, color=mycolors[1], linewidth=2)
ax.fill_between(x, y1=y2, y2=0, label=columns[0], alpha=0.5, color=mycolors[0], linewidth=2)

# Decorations
ax.set_title('Personal Savings Rate vs Median Duration of Unemployment', fontsize=18)
ax.set(ylim=[0.30])
ax.legend(loc='best', fontsize=12)
plt.xticks(x[::50], fontsize=10, horizontalalignment='center')
plt.yticks(np.arange(2.5.30.0.2.5), fontsize=10)
plt.xlim(-10, x[-1])

# Draw Tick lines  
for y in np.arange(2.5.30.0.2.5):    
    plt.hlines(y, xmin=0, xmax=len(x), colors='black', alpha=0.3, linestyles="--", lw=0.5)

# Lighten borders
plt.gca().spines["top"].set_alpha(0)
plt.gca().spines["bottom"].set_alpha(3.)
plt.gca().spines["right"].set_alpha(0)
plt.gca().spines["left"].set_alpha(3.)
plt.show()
Copy the code

45 Calendar Heat Map

Calendar maps are an alternative and less preferred option for visualizing time-based data compared to time series. While visually appealing, the numbers are not obvious. However, it does a good job of depicting extreme values and holiday effects.

PIP install calmap
import matplotlib as mpl
import calmap

# Import Data
df = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/yahoo.csv", parse_dates=['date'])
df.set_index('date', inplace=True)

# Plot
plt.figure(figsize=(16.10), dpi= 80)
calmap.calendarplot(df['2014'] ['VIX.Close'], fig_kws={'figsize': (16.10)}, yearlabel_kws={'color':'black'.'fontsize':14}, subplot_kws={'title':'Yahoo Stock Prices'})
plt.show()
Copy the code

46 Seasonal Plot

Seasonal charts can be used to compare time series for the same day (year/month/week, etc.) in the previous season.

from dateutil.parser import parse

# Import Data
df = pd.read_csv('https://github.com/selva86/datasets/raw/master/AirPassengers.csv')

# Prepare data
df['year'] = [parse(d).year for d in df.date]
df['month'] = [parse(d).strftime('%b') for d in df.date]
years = df['year'].unique()

# Draw Plot
mycolors = ['tab:red'.'tab:blue'.'tab:green'.'tab:orange'.'tab:brown'.'tab:grey'.'tab:pink'.'tab:olive'.'deeppink'.'steelblue'.'firebrick'.'mediumseagreen']      
plt.figure(figsize=(16.10), dpi= 80)

for i, y in enumerate(years):
    plt.plot('month'.'traffic', data=df.loc[df.year==y, :], color=mycolors[i], label=y)
    plt.text(df.loc[df.year==y, :].shape[0] -9., df.loc[df.year==y, 'traffic'] [-1:].values[0], y, fontsize=12, color=mycolors[i])

# Decoration
plt.ylim(50.750)
plt.xlim(-0.3.11)
plt.ylabel('$Air Traffic$')
plt.yticks(fontsize=12, alpha=7.)
plt.title("Monthly Seasonal Plot: Air Passengers Traffic (1949 - 1969)", fontsize=22)
plt.grid(axis='y', alpha=3.)

# Remove borders
plt.gca().spines["top"].set_alpha(0.0)    
plt.gca().spines["bottom"].set_alpha(0.5)
plt.gca().spines["right"].set_alpha(0.0)    
plt.gca().spines["left"].set_alpha(0.5)   
# plt.legend(loc='upper right', ncol=2, fontsize=12)
plt.show()
Copy the code

7. Groups

47 Dendrogram

A tree graph groups similar points together based on a given distance measure and organizes them into tree-like links based on their similarity.

import scipy.cluster.hierarchy as shc

# Import Data
df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/USArrests.csv')

# Plot
plt.figure(figsize=(16.10), dpi= 80)  
plt.title("USArrests Dendograms", fontsize=22)  
dend = shc.dendrogram(shc.linkage(df[['Murder'.'Assault'.'UrbanPop'.'Rape']], method='ward'), labels=df.State.values, color_threshold=100)  
plt.xticks(fontsize=12)
plt.show()
Copy the code

48 Cluster Plot

Cluster plots can be used to divide points belonging to the same Cluster. Below is a representative example of the five groups of STATES in the United States, based on the USUB data set. This figure uses the Murder and Attack columns as the X and Y axes. Alternatively, you can use the first to the main component as the X and Y axes.

from sklearn.cluster import AgglomerativeClustering
from scipy.spatial import ConvexHull

# Import Data
df = pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/USArrests.csv')

# Agglomerative Clustering
cluster = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='ward')  
cluster.fit_predict(df[['Murder'.'Assault'.'UrbanPop'.'Rape']])  

# Plot
plt.figure(figsize=(14.10), dpi= 80)  
plt.scatter(df.iloc[:,0], df.iloc[:,1], c=cluster.labels_, cmap='tab10')  

# Encircle
def encircle(x,y, ax=None, **kw) :
    if not ax: ax=plt.gca()
    p = np.c_[x,y]
    hull = ConvexHull(p)
    poly = plt.Polygon(p[hull.vertices,:], **kw)
    ax.add_patch(poly)

# Draw polygon surrounding vertices    
encircle(df.loc[cluster.labels_ == 0.'Murder'], df.loc[cluster.labels_ == 0.'Assault'], ec="k", fc="gold", alpha=0.2, linewidth=0)
encircle(df.loc[cluster.labels_ == 1.'Murder'], df.loc[cluster.labels_ == 1.'Assault'], ec="k", fc="tab:blue", alpha=0.2, linewidth=0)
encircle(df.loc[cluster.labels_ == 2.'Murder'], df.loc[cluster.labels_ == 2.'Assault'], ec="k", fc="tab:red", alpha=0.2, linewidth=0)
encircle(df.loc[cluster.labels_ == 3.'Murder'], df.loc[cluster.labels_ == 3.'Assault'], ec="k", fc="tab:green", alpha=0.2, linewidth=0)
encircle(df.loc[cluster.labels_ == 4.'Murder'], df.loc[cluster.labels_ == 4.'Assault'], ec="k", fc="tab:orange", alpha=0.2, linewidth=0)

# Decorations
plt.xlabel('Murder'); plt.xticks(fontsize=12)
plt.ylabel('Assault'); plt.yticks(fontsize=12)
plt.title('Agglomerative Clustering of USArrests (5 Groups)', fontsize=22)
plt.show()
Copy the code

49 Andrews Curve

The Andrews curve helps visualize whether there is an inherent grouping based on the digital features of a given grouping. If elements (columns in the dataset) cannot be partitioned (CYL), then the lines will not be well isolated, as shown below.

from pandas.plotting import andrews_curves

# Import
df = pd.read_csv("https://github.com/selva86/datasets/raw/master/mtcars.csv")
df.drop(['cars'.'carname'], axis=1, inplace=True)

# Plot
plt.figure(figsize=(12.9), dpi= 80)
andrews_curves(df, 'cyl', colormap='Set1')

# Lighten borders
plt.gca().spines["top"].set_alpha(0)
plt.gca().spines["bottom"].set_alpha(3.)
plt.gca().spines["right"].set_alpha(0)
plt.gca().spines["left"].set_alpha(3.)

plt.title('Andrews Curves of mtcars', fontsize=22)
plt.xlim(-3.3)
plt.grid(alpha=0.3)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
Copy the code

Coordinates of 50 Parallel Coordinates

Parallel coordinates help visualize whether features help isolate groups effectively. If isolation is implemented, this characteristic can be very useful in predicting this group.

from pandas.plotting import parallel_coordinates

# Import Data
df_final = pd.read_csv("https://raw.githubusercontent.com/selva86/datasets/master/diamonds_filter.csv")

# Plot
plt.figure(figsize=(12.9), dpi= 80)
parallel_coordinates(df_final, 'cut', colormap='Dark2')

# Lighten borders
plt.gca().spines["top"].set_alpha(0)
plt.gca().spines["bottom"].set_alpha(3.)
plt.gca().spines["right"].set_alpha(0)
plt.gca().spines["left"].set_alpha(3.)

plt.title('Parallel Coordinated of Diamonds', fontsize=22)
plt.grid(alpha=0.3)
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
plt.show()
Copy the code