3. Miscellaneous

3.1. Annotation

Annotation can be used to make graph more readable as show in Fig. 3.1. Text is added to graph using ‘annotate()’ command with two different methods as shown in line 25 and 40 in Listing 3.1. Also, ‘text()’ command (at line 49) is used to add text to the figure.

Listing 3.1 Annotation, Fig. 3.1
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#annotateEx.py
import numpy as np
import matplotlib.pyplot as plt

# close all the figures, if open from previous commands
plt.close('all') 

############ Sin(x) ####################
x=np.linspace(0, 2*np.pi, 100) 
sinx=np.sin(x) # calculate sin(x)
plt.plot(x,sinx, label='sin') # legend 

############ Legend ####################
plt.legend(loc="best") #show legend

#### Lable and Grid ####################
plt.xlabel("Radian") # x label 
plt.ylabel("Amplitude") # y label

############# Annotate ######################
#1. 
# other arrow style 
# '-', '->', '-[', '<-', '<->', 'fancy', 'simple', 'wedge' 
#sin(pi/2)=1
plt.annotate(r'$sin(\frac{\pi}{2})=1$', 
             fontsize=16,
             xy=(1.5, 1), xytext=(1 , 0.5),
             arrowprops=dict(arrowstyle="->"),
        )

# 2. 
#=============================================================
# width: The width of the arrow in points
# frac: The fraction of the arrow length occupied by the head
# headwidth: The width of the base of the arrow head in points
# shrink: Moves the tip and the base of the arrow some percent 
# away from the annotated point and text, 
#=============================================================
#sin(3*pi/2)=-1
plt.annotate(r'$sin(\frac{3\pi}{2})=-1$', 
             fontsize=18,
             xy=(4.5, -1), xytext=(1.5 , -0.5),
             arrowprops=dict(facecolor='red', shrink = 0.04, 
                             connectionstyle="arc3,rad=.2"),
        )       
     
# 3.          
#################### Add text to plot ###########           
plt.text(5, 0.5, 'This is \nSine wave');
        
plt.show() #display the plot
../_images/annotateEx.png

Fig. 3.1 Annotation, Listing 3.1

3.2. Sharing Axis

Listing Listing 3.2, Listing 3.3 and Listing 3.4 create the instances of figure() and subplot() functions of matplotlib to generate various plots.

3.2.1. Common axis for two plots

Here x axis is common for two different plots. Further, in one plot log y-axis is used.

  • Explanation Listing 3.2

    Line 11 creates an instance ‘fig1’ of figure() function. Then subfig1 and subfig2 instances of ‘fig1’ are created in line 14 and 15. ‘twinx()’ command in line 18, shares the x-axis for both the plots.

    Line 22-24 set the various parameter for subfig1; also note that ‘set_’ is used for x and y labels. Then line 27-28 plots the second figure. Finally line 30 displays both the plots as shown in Fig. 3.2

Listing 3.2 Sharing Axis, Fig. 3.2
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#shareaxisEx.py
import numpy as np
import matplotlib.pyplot as plt

N=100
x=np.linspace(0.1,4, N)
e1 = np.exp(x)
e2 = np.exp(-x)

# create an object 'fig1'  of figure() 
fig1 = plt.figure()

# create two instances of fig1 at location 1,1,1
subfig1 = fig1.add_subplot(1,1,1)
subfig2 = fig1.add_subplot(1,1,1)

# share the x-axis for both plot
subfig2 = subfig1.twinx()

# plot subfig1
# semilogy for log 'y' axis, for log x use semilogx
subfig1.semilogy(x, e1) 
subfig1.set_ylabel("log scale: exp(x)")
subfig1.set_xlabel("x-->")

# plot subfig2
subfig2.plot(x, e2, 'r')
subfig2.set_ylabel("simple scale: exp(-x)")

plt.show()
../_images/shareaxisEx.png

Fig. 3.2 Shared x-axis by two figures, Listing 3.2

3.2.2. Sharing Axis-ticks

Here, same y-axis ticks (i.e. [-3, 2]) are used for two subplots as illustrated in Fig. 3.3 using Listing 3.3. In the listing, line 15 and 16 create two subplots. Further, line 15 contains ‘sharey’ parameter which sets ticks in the y-axis of subfig2 equal to subfig1.

Listing 3.3 Sharing Y Axis ticks, Fig. 3.3
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#subplotEx2.py
import numpy as np
import matplotlib.pyplot as plt

N=100
x=np.arange(N)
rn = np.random.randn(N)
r = np.random.rand(N)

# create an object 'fig1'  of figure() 
fig1 = plt.figure()

# create two instances of fig1
subfig1 = fig1.add_subplot(2,1,1)
subfig2 = fig1.add_subplot(2,1,2, sharey = subfig1) #share y axis

# plot figures
subfig1.plot(x, rn)
subfig2.plot(x, r)
plt.show()
../_images/shareaxisEx2.png

Fig. 3.3 Same Y axis values, Listing 3.3

3.3. Add legend outside the plot

In Listing 3.4, legends are placed outside the figure as shown in Fig. 3.4. It can be quite useful, when we have large number of figures in a single plot. Note that, in line 12, instance of subplot is created directly; whereas in Fig. 3.3, subplot are created using instances of figure(), which require ‘add_subplot’ command as shown in line 14 and 15 there.

Listing 3.4 Legend outside the plot, Fig. 3.4
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#legendPosEx.py
import matplotlib.pyplot as plt
import numpy as np

# close all the figures, if open from previous commands
plt.close('all') 

ur = np.random.rand(100)
nr = np.random.randn(100)
x=np.linspace(0,3, 100)

ax = plt.subplot(1,1,1)

ax.plot(x, label="Line")
ax.plot(ur, label="Uniform random number")
ax.plot(nr, label="Normal random number")
ax.set_title("Legend outside the plot")

# Plot position and shriking to create space for legends
box = ax.get_position()
ax.set_position([box.x0, box.y0 + box.height * 0.2,
                 box.width, box.height * 0.8])

# Add legend below the axis
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.05),
          fancybox=True, shadow=True, ncol=2)

plt.show()
../_images/legendPosEx.png

Fig. 3.4 Legend outside the plot, Listing 3.4