Due to various adult circumstances, you may want to ** omit the middle of the graph with a wavy line **. This is an explanation of how to create such a graph using matplotlib.
We have confirmed the execution and operation with Python 3.6.9 (Google Colab. Environment).
Execution environment
japanize-matplotlib 1.0.5
matplotlib 3.1.3
matplotlib-venn 0.11.5
In order to make matplotlib ** Japanese compatible ** in Google Colab. Environment, do as follows.
Preparation for using Japanese in the graph
!pip install japanize-matplotlib
import japanize_matplotlib
First, let's draw a bar graph normally.
Create a bar chart normally
left = np.array(['Fukushima', 'Aichi', 'Kanagawa', 'Osaka', 'Tokyo'])
height = np.array([160, 220, 280, 360, 1820])
plt.figure(figsize=(3,4), dpi=160)
plt.bar(left,height) #bar graph
plt.yticks(np.arange(0,1800+1,200)) #X-axis scale from 0 to 1900 in 200 increments
plt.gcf().patch.set_facecolor('white') #Set the background color to "white"
The execution result is as follows. The protrusion of Tokyo is very noticeable.
Step.1
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.path import Path
left = np.array(['Fukushima', 'Aichi', 'Kanagawa', 'Osaka', 'Tokyo'])
height = np.array([160, 220, 280, 360, 1820])
#Subplot Prepare a 2-by-1 subplot
fig, ax = plt.subplots(nrows=2, figsize=(3,4), dpi=160, sharex='col',
gridspec_kw={'height_ratios': (1,2)} )
fig.patch.set_facecolor('white') #Set the background color to "white"
ax[0].bar(left,height) #Upper row
ax[1].bar(left,height) #Lower row
gridspec_kw = {'height_ratios': (1,2)}
is set so that the height ratio of the top and bottom is $ 1: 2 $. The execution result is as follows.
There is a gap between the upper and lower subplots, so I will erase it.
Step.2
#Set the vertical spacing between subplots to zero
fig.subplots_adjust(hspace=0.0)
The execution result is as follows.
Hides the borders of the upper and lower graphs (= the bottom of the upper subplot, the top of the lower subplot). It also sets the Y-axis display range and scale for each subplot. At this time, make sure that the ** Y-axis display range ratio ** between the subplots is the same as the 'height_ratios': (1,2)
specified in Step.1.
Step.3
#Lower subplot
ax[1].set_ylim(0,400) #Section width 400
ax[1].set_yticks(np.arange(0,300+1,100))
#Upper subplot
ax[0].set_ylim(1750,1950) #Section width 200
ax[0].set_yticks((1800,1900))
#Hide the top edge of the lower plot area
ax[1].spines['top'].set_visible(False)
#Hide the bottom of the upper plot area, hide the X-axis scale and labels
ax[0].spines['bottom'].set_visible(False)
ax[0].tick_params(axis='x', which='both', bottom=False, labelbottom=False)
The execution result is as follows.
I will draw a nyoro (wavy line) indicating that the middle section is omitted.
Step.4
d1 = 0.02 #X-axis protrusion amount
d2 = 0.03 #Nyoro wave height
wn = 21 #Number of Nyoro waves (specify an odd value)
pp = (0,d2,0,-d2)
px = np.linspace(-d1,1+d1,wn)
py = np.array([1+pp[i%4] for i in range(0,wn)])
p = Path(list(zip(px,py)), [Path.MOVETO]+[Path.CURVE3]*(wn-1))
line1 = mpatches.PathPatch(p, lw=4, edgecolor='black',
facecolor='None', clip_on=False,
transform=ax[1].transAxes, zorder=10)
line2 = mpatches.PathPatch(p,lw=3, edgecolor='white',
facecolor='None', clip_on=False,
transform=ax[1].transAxes, zorder=10,
capstyle='round')
a = ax[1].add_patch(line1)
a = ax[1].add_patch(line2)
The execution result is as follows.
Setting the drawing parameters as d1 = 0.1
, wn = 41
gives:
Whole code
%reset -f
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.path import Path
left = np.array(['Fukushima', 'Aichi', 'Kanagawa', 'Osaka', 'Tokyo'])
height = np.array([160, 220, 280, 360, 1820])
#Subplot Prepare a 2-by-1 subplot
fig, ax = plt.subplots(nrows=2, figsize=(3,4), dpi=160, sharex='col',
gridspec_kw={'height_ratios': (1,2)} )
fig.patch.set_facecolor('white') #Set the background color to "white"
ax[0].bar(left,height) #Upper row
ax[1].bar(left,height) #Lower row
#Set the vertical spacing between subplots to zero
fig.subplots_adjust(hspace=0.0)
#Lower subplot
ax[1].set_ylim(0,400) #Section width 400
ax[1].set_yticks(np.arange(0,300+1,100))
#Upper subplot
ax[0].set_ylim(1750,1950) #Section width 200
ax[0].set_yticks((1800,1900))
#Hide the top edge of the lower plot area
ax[1].spines['top'].set_visible(False)
#Hide the bottom of the upper plot area, hide the X-axis scale and labels
ax[0].spines['bottom'].set_visible(False)
ax[0].tick_params(axis='x', which='both', bottom=False, labelbottom=False)
##Nyoro line drawing
d1 = 0.02 #X-axis protrusion amount
d2 = 0.03 #Nyoro wave height
wn = 21 #Number of Nyoro waves (specify an odd value)
pp = (0,d2,0,-d2)
px = np.linspace(-d1,1+d1,wn)
py = np.array([1+pp[i%4] for i in range(0,wn)])
p = Path(list(zip(px,py)), [Path.MOVETO]+[Path.CURVE3]*(wn-1))
line1 = mpatches.PathPatch(p, lw=4, edgecolor='black',
facecolor='None', clip_on=False,
transform=ax[1].transAxes, zorder=10)
line2 = mpatches.PathPatch(p,lw=3, edgecolor='white',
facecolor='None', clip_on=False,
transform=ax[1].transAxes, zorder=10,
capstyle='round')
a = ax[1].add_patch(line1)
a = ax[1].add_patch(line2)
Recommended Posts