#==============================================================================
# 第七章 使用正确的图表理解数据
# 7.1 简介
#==============================================================================
#==============================================================================
# 7.2 理解对数图
#==============================================================================
from matplotlib import pyplot as plt
import numpy as np
'''
根据经验,以下情况使用对数标度:
1.当要展示的数据的值跨越好几个量级时
2.当要展示的数据有朝向大值(一些数据点比其他数据大很多)的倾斜度。
3.当要展示变化率(增长率),而不是值的变化
'''
x = np.linspace(1, 10)
y = [10 ** el for el in x] #
z = [2 * el for el in x]
fig = plt.figure(figsize=(10, 8))
ax1 = fig.add_subplot(2, 2, 1)
ax1.plot(x, y, color='blue')
ax1.set_yscale('log') #对数标度
ax1.set_title(r'Logarithmic plot of $ {10}^{x} $ ')
ax1.set_ylabel(r'$ {y} = {10}^{x} $')
plt.grid(b=True, which='both', axis='both')
ax2 = fig.add_subplot(2, 2, 2)
ax2.plot(x, y, color='red')
ax2.set_yscale('linear') #线性标度
ax2.set_title(r'Linear plot of $ {10}^{x} $ ')
ax2.set_ylabel(r'$ {y} = {10}^{x} $')
plt.grid(b=True, which='both', axis='both')
ax3 = fig.add_subplot(2, 2, 3)
ax3.plot(x, z, color='green')
ax3.set_yscale('log') #对数标度
ax3.set_title(r'Logarithmic plot of $ {2}*{x} $ ')
ax3.set_ylabel(r'$ {y} = {2}*{x} $')
plt.grid(b=True, which='both', axis='both')
ax4 = fig.add_subplot(2, 2, 4)
ax4.plot(x, z, color='magenta')
ax4.set_yscale('linear') #线性标度
ax4.set_title(r'Linear plot of $ {2}*{x} $ ')
ax4.set_ylabel(r'$ {y} = {2}*{x} $')
plt.grid(b=True, which='both', axis='both')
plt.show()
#==============================================================================
# 7.3 理解频谱图
#==============================================================================
安装libsndfile1系统库来读/写音频文件
sudu apt-get install libasound1-dev
sudu apt-get install libasound2-dev
pip install scikits.audiolab
import os
from math import floor, log
from scikits.audiolab import Sndfile
import numpy as np
from matplotlib import pyplot as plt
soundfile = Sndfile("test.wav")
samplerate = soundfile.samplerate
start_sec = 0
stop_sec = 5
start_frame = start_sec * soundfile.samplerate
stop_frame = stop_sec * soundfile.samplerate
soundfile.seek(start_frame)
delta_frames = stop_frame - start_frame
sample = soundfile.read_frames(delta_frames)
map = 'CMRmap'
fig = plt.figure(figsize=(10, 6), )
ax = fig.add_subplot(111)
NFFT = 128
noverlap = 65
pxx, freq, t, cax = ax.specgram(sample, Fs=soundfile.samplerate,
NFFT=NFFT, noverlap=noverlap,
cmap=plt.get_cmap(map))
plt.colorbar(cax)
plt.xlabel("Times [sec]")
plt.ylabel("Frequency [Hz]")
plt.show()
-----------------------------------------------
import numpy
import matplotlib.pyplot as plt
def _get_mask(t, t1, t2, lvl_pos, lvl_neg):
if t1 >= t2:
raise ValueError("t1 must be less than t2")
return numpy.where(numpy.logical_and(t > t1, t < t2), lvl_pos, lvl_neg)
def generate_signal(t):
sin1 = numpy.sin(2 * numpy.pi * 100 * t)
sin2 = 2 * numpy.sin(2 * numpy.pi * 200 * t)
# add interval of high pitched signal
masks = _get_mask(t, 2, 4, 1.0, 0.0) + \
_get_mask(t, 14, 15, 1.0, 0.0)
sin2 = sin2 * masks
noise = 0.02 * numpy.random.randn(len(t))
final_signal = sin1 + sin2 + noise
return final_signal
if __name__ == '__main__':
step = 0.001
sampling_freq=1000
t = numpy.arange(0.0, 20.0, step)
y = generate_signal(t)
# we can visualize this now
# in time
ax1 = plt.subplot(211)
plt.plot(t, y)
# and in frequency
plt.subplot(212)
plt.specgram(y, NFFT=1024, noverlap=900,
Fs=sampling_freq, cmap=plt.cm.gist_heat)
plt.show()
#==============================================================================
# 7.4 创建火柴杆图
#==============================================================================
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 20, 50)
y = np.sin(x + 1) + np.cos(x ** 2)
bottom = -0.1 # 基线位置
# True,hold current axes for further plotting
# False,opposite. clear and use new figure/plot
hold = False #把所有当前图形放在当前坐标轴上
label = "delta" #设置火柴杠图图例
'''
markerline:保存了表示火柴杆本身的线条引用,仅渲染了标记,不包括连接标记的线条
stemlines:保存了表示stemlines原点的水平线条的引用。
baseline:表示茎线的集合
'''
markerline, stemlines, baseline = plt.stem(x, y, bottom=bottom,label=label, hold=hold)
plt.setp(markerline, color='red', marker='o')
plt.setp(stemlines, color='blue', linestyle=':')
plt.setp(baseline, color='grey', linewidth=2, linestyle='-')
# draw a legend
plt.legend()
plt.show()
·
#==============================================================================
# 7.5 绘制矢量场流线图
#==============================================================================
import matplotlib.pyplot as plt
import numpy as np
Y, X = np.mgrid[0:5:100j, 0:5:100j]
U = X # np.sin(X)
V = Y # np.sin(Y)
from pprint import pprint
print "X"
pprint(X)
print "Y"
pprint(Y)
plt.streamplot(X, Y, U, V)
plt.show()
#==============================================================================
# 7.6 使用颜色表
#==============================================================================
数据没有与红色/绿色有很强的关联时,要尽可能的避免使用这两种颜色。
颜色表:
Sequential:表示同一颜色从低饱和度到高饱和度的两个色调的单色颜色表。
Diverging:表示中间值,是颜色的中值,然后颜色范围在高和低两个方向上变化到两个不同的色调。
例如中值为0,能清晰的显示负值和正值之间的区别。
Qualitative:对于数据没有固定的顺序,并且想要让不同种类的数据之间能轻易的区分开的情况,可选用该颜色表。
Cyclic:当数据可以围绕端点值显示的时候,比较方便,例如一天的时间,风向,相位角。
matplotlib预定义的颜色表:autumn、bone、cool、copper、flag、gray、hot、hsv、jet、pink、prism、sprint、summer、winter、spectral
Yorick科学可视化包:gist_earth、gist_heat、gist_ncar、gist_rainbow、gist_stern
ColorBrewer颜色表
Diverging:中间亮度最高,向两端递减
Sequential:亮度单调地递减
Qualitative:不同种类的颜色用来区分不同的数据类别
其他:
brg:表示一个发散型的蓝、红、绿颜色表
bwr:发散型蓝、白、红颜色表
seismic:发散蓝、白、红
coolwarm:对于3D阴影,色盲和颜色排序非常有用
rainbow:发散亮度的紫、蓝、绿、黄、橙、红光谱
terrain:地图标记的颜色(蓝、绿、黄、棕、白)
颜色表名_r表示反转。
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
red_yellow_green = ['#d73027', '#f46d43', '#fdae61',
'#fee08b', '#ffffbf', '#d9ef8b',
'#a6d96a', '#66bd63', '#1a9850']
fig,ax = plt.subplots(1)
for i in range(9):
y = np.random.normal(size=1000).cumsum()
x = np.arange(1000)
ax.scatter(x, y, label=str(i), linewidth=0.1, edgecolors='grey', facecolor=red_yellow_green[i])
ax.legend()
plt.show()
#==============================================================================
# 7.7 使用散点图和直方图
#==============================================================================
散点图
-----------------------------------------------------------
import matplotlib.pyplot as plt
import numpy as np
# import the data
from ch07_search_data import DATA
data = DATA, data1 = np.random.random(365)
assert len(data) == len(data1)
fig = plt.figure()
ax1 = fig.add_subplot(221)
ax1.scatter(data, data1, alpha=0.5)
ax1.set_title('No correlation')
ax1.grid(True)
ax2 = fig.add_subplot(222)
ax2.scatter(data1, data1, alpha=0.5)
ax2.set_title('Ideal positive correlation')
ax2.grid(True)
ax3 = fig.add_subplot(223)
ax3.scatter(data1, data1*-1, alpha=0.5)
ax3.set_title('Ideal negative correlation')
ax3.grid(True)
ax4 = fig.add_subplot(224)
ax4.scatter(data1, data1+data, alpha=0.5)
ax4.set_title('Non ideal positive correlation')
ax4.grid(True)
plt.tight_layout()
plt.show()
直方图
-----------------------------------------------------------
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
def scatterhist(x, y, figsize=(8,8)):
"""
Create simple scatter & histograms of data x, y inside given plot
@param figsize: Figure size to create figure
@type figsize: Tuple of two floats representing size in inches
@param x: X axis data set
@type x: np.array
@param y: Y axis data set
@type y: np.array
"""
_, scatter_axes = plt.subplots(figsize=figsize)
# the scatter plot:
scatter_axes.scatter(x, y, alpha=0.5)
scatter_axes.set_aspect(1.)
divider = make_axes_locatable(scatter_axes)
axes_hist_x = divider.append_axes(position="top", sharex=scatter_axes, size=1, pad=0.1)
axes_hist_y = divider.append_axes(position="right", sharey=scatter_axes, size=1, pad=0.1)
binwidth = 0.25# compute bins accordingly
# global max value in both data sets
xymax = np.max([np.max(np.fabs(x)), np.max(np.fabs(y))])
# number of bins
bincap = int(xymax / binwidth) * binwidth
bins = np.arange(-bincap, bincap, binwidth)
nx, binsx, _ = axes_hist_x.hist(x, bins=bins, histtype='stepfilled',
orientation='vertical')
ny, binsy, _ = axes_hist_y.hist(y, bins=bins, histtype='stepfilled',
orientation='horizontal')
tickstep = 50
ticksmax = np.max([np.max(nx), np.max(ny)])
xyticks = np.arange(0, ticksmax + tickstep, tickstep)
# hide x and y ticklabels on histograms
for tl in axes_hist_x.get_xticklabels():
tl.set_visible(False)
axes_hist_x.set_yticks(xyticks)
for tl in axes_hist_y.get_yticklabels():
tl.set_visible(False)
axes_hist_y.set_xticks(xyticks)
plt.show()
if __name__ == '__main__':
# import the data
from ch07_search_data import DATA
d = DATA
# Now let's generate random data for the same period
d1 = np.random.random(365)
assert len(d) == len(d1)
# try with the random data
# d = np.random.randn(1000)
# d1 = np.random.randn(1000)
scatterhist(d, d1)
#==============================================================================
# 7.8 绘制两个变量之间的互相图形
#==============================================================================
绘两个数据集之间的相互关系
import matplotlib.pyplot as plt
import numpy as np
# import the data
from ch07_search_data import DATA
data = DATA
total = sum(data)
av = total / len(data)
z = [i - av for i in data]
av1 = sum(data1) / len(data1)
z1 = [i - av1 for i in data1]
data1 = np.random.random(365)
assert len(data) == len(data1)
fig = plt.figure()
ax1 = fig.add_subplot(311)
ax1.plot(data)
ax1.set_xlabel('Google Trends data for "flowers"')
ax2 = fig.add_subplot(312)
ax2.plot(data1)
ax2.set_xlabel('Random data')
ax3 = fig.add_subplot(313)
ax3.set_xlabel('Cross correlation of random data')
ax3.xcorr(z, z1, usevlines=True, maxlags=None, normed=True, lw=2)
ax3.grid(True)
plt.ylim(-1,1)
plt.tight_layout()
plt.show()
#==============================================================================
# 7.9 自相关的重要性
#==============================================================================
import matplotlib.pyplot as plt
import numpy as np
from ch07_search_data import DATA as data
total = sum(data)
av = total / len(data)
z = [i - av for i in data]
fig = plt.figure()
plt.title('Comparing autocorrelations')
ax1 = fig.add_subplot(221)
ax1.plot(data)
ax1.set_xlabel('Google Trends data for "flowers"')
ax2 = fig.add_subplot(222)
ax2.acorr(z, usevlines=True, maxlags=None, normed=True, lw=2)
ax2.grid(True)
ax2.set_xlabel('Autocorrelation')
data1 = np.random.random(365)
assert len(data) == len(data1)
total = sum(data1)
av = total / len(data1)
z = [i - av for i in data1]
ax3 = fig.add_subplot(223)
ax3.plot(data1)
ax3.set_xlabel('Random data')
ax4 = fig.add_subplot(224)
ax4.set_xlabel('Autocorrelation of random data')
ax4.acorr( z, usevlines=True, maxlags=None, normed=True, lw=2)
ax4.grid(True)
plt.show()
#==============================================================================
# 第八章 更多matplotlib
# 8.2 绘制风杠barbs
#==============================================================================
import matplotlib.pyplot as plt
import numpy as np
'''
barbcolor:风杠中除旗标颜色
flagcolor:风杠中旗标颜色
facecolor:默认,前两者将覆盖这个
spacing:旗标/风杠属性间的间距
height:箭杆到旗标或者风杠顶部的距离
width:旗标的宽度
emptybarb:定义最小值的圆圈的半径
'''
V = [0, -5, -10, -15, -30, -40, -50, -60, -100]
U = np.zeros(len(V))
y = np.ones(len(V))
x = [0, 5, 10, 15, 30, 40, 50, 60, 100]
plt.barbs(x, y, U, V, length=9)
plt.xticks(x)
plt.ylim(0.98, 1.05)
plt.show()
----------------------------------------------
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-20, 20, 8)
y = np.linspace( 0, 20, 8)
# make 2D coordinates
X, Y = np.meshgrid(x, y)
U, V = X + 25, Y - 35
# plot the barbs
plt.subplot(1,2,1)
plt.barbs(X, Y, U, V, flagcolor='green', alpha=0.75)
plt.grid(True, color='gray')
# compare that with quiver / arrows
plt.subplot(1,2,2)
plt.quiver(X, Y, U, V, facecolor='red', alpha=0.75)
# misc settings
plt.grid(True, color='grey')
plt.show()
#==============================================================================
# 8.3 绘制箱线图
#==============================================================================
import matplotlib.pyplot as plt
PROCESSES = {
"A": [12, 15, 23, 24, 30, 31, 33, 36, 50, 73],
"B": [6, 22, 26, 33, 35, 47, 54, 55, 62, 63],
"C": [2, 3, 6, 8, 13, 14, 19, 23, 60, 69],
"D": [1, 22, 36, 37, 45, 47, 48, 51, 52, 69],
}
DATA = PROCESSES.values()
LABELS = PROCESSES.keys()
plt.boxplot(DATA, widths=0.3)
# set ticklabel to process name
plt.gca().xaxis.set_ticklabels(LABELS)
# some makeup (removing chartjunk)
for spine in plt.gca().spines.values():
spine.set_visible(False)
plt.gca().xaxis.set_ticks_position('none')
plt.gca().yaxis.set_ticks_position('left')
plt.gca().grid(axis='y', color='gray')
# set axes labels
plt.ylabel("Errors observed over defined period.")
plt.xlabel("Process observed over defined period.")
plt.show()
#==============================================================================
# 8.4 绘制甘特图
#==============================================================================
from datetime import datetime
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
import matplotlib.dates as mdates
import logging
class Gantt(object):
# from http://colorbrewer2.org/
RdYlGr = ['#d73027', '#f46d43', '#fdae61',
'#fee08b', '#ffffbf', '#d9ef8b',
'#a6d96a', '#66bd63', '#1a9850']
POS_START = 1.0
POS_STEP = 0.5
def __init__(self, tasks):
self._fig = plt.figure()
self._ax = self._fig.add_axes([0.1, 0.1, .75, .5])
self.tasks = tasks[::-1]
def _format_date(self, date_string):
try:
date = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S')
except ValueError as err:
logging.error("String '{0}' can not be converted to datetime object: {1}"
.format(date_string, err))
sys.exit(-1)
mpl_date = mdates.date2num(date)
return mpl_date
def _plot_bars(self):
i = 0
for task in self.tasks:
start = self._format_date(task['start'])
end = self._format_date(task['end'])
bottom = (i * Gantt.POS_STEP) + Gantt.POS_START
width = end - start
self._ax.barh(bottom, width, left=start, height=0.3,
align='center', label=task['label'],
color = Gantt.RdYlGr[i])
i += 1
def _configure_yaxis(self):'''y axis'''
task_labels = [t['label'] for t in self.tasks]
pos = self._positions(len(task_labels))
ylocs = self._ax.set_yticks(pos)
ylabels = self._ax.set_yticklabels(task_labels)
plt.setp(ylabels, size='medium')
def _configure_xaxis(self):''''x axis'''
self._ax.xaxis_date()
# format date to ticks on every 7 days
rule = mdates.rrulewrapper(mdates.DAILY, interval=7)
loc = mdates.RRuleLocator(rule)
formatter = mdates.DateFormatter("%d %b")
self._ax.xaxis.set_major_locator(loc)
self._ax.xaxis.set_major_formatter(formatter)
xlabels = self._ax.get_xticklabels()
plt.setp(xlabels, rotation=30, fontsize=9)
def _configure_figure(self):
self._configure_xaxis()
self._configure_yaxis()
self._ax.grid(True, color='gray')
self._set_legend()
self._fig.autofmt_xdate()
def _set_legend(self):
font = font_manager.FontProperties(size='small')
self._ax.legend(loc='upper right', prop=font)
def _positions(self, count):
end = count * Gantt.POS_STEP + Gantt.POS_START
pos = np.arange(Gantt.POS_START, end, Gantt.POS_STEP)
return pos
def show(self):
self._plot_bars()
self._configure_figure()
plt.show()
if __name__ == '__main__':
TEST_DATA = (
{ 'label': 'Research', 'start':'2013-10-01 12:00:00', 'end': '2013-10-02 18:00:00'}, # @IgnorePep8
{ 'label': 'Compilation', 'start':'2013-10-02 09:00:00', 'end': '2013-10-02 12:00:00'}, # @IgnorePep8
{ 'label': 'Meeting #1', 'start':'2013-10-03 12:00:00', 'end': '2013-10-03 18:00:00'}, # @IgnorePep8
{ 'label': 'Design', 'start':'2013-10-04 09:00:00', 'end': '2013-10-10 13:00:00'}, # @IgnorePep8
{ 'label': 'Meeting #2', 'start':'2013-10-11 09:00:00', 'end': '2013-10-11 13:00:00'}, # @IgnorePep8
{ 'label': 'Implementation', 'start':'2013-10-12 09:00:00', 'end': '2013-10-22 13:00:00'}, # @IgnorePep8
{ 'label': 'Demo', 'start':'2013-10-23 09:00:00', 'end': '2013-10-23 13:00:00'}, # @IgnorePep8
)
gantt = Gantt(TEST_DATA)
gantt.show()
#==============================================================================
# 8.5 绘制误差条
#==============================================================================
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as sc
TEST_DATA = np.array([[1,2,3,2,1,2,3,4,2,3,2,1,2,3,4,4,3,2,3,2,3,2,1],
[5,6,5,4,5,6,7,7,6,7,7,2,8,7,6,5,5,6,7,7,7,6,5],
[9,8,7,8,8,7,4,6,6,5,4,3,2,2,2,3,3,4,5,5,5,6,1],
[3,2,3,2,2,2,2,3,3,3,3,4,4,4,4,5,6,6,7,8,9,8,5],
])
y = np.mean(TEST_DATA, axis=1, dtype=np.float64)
#计算出95%的置信区间
ci95 = np.abs(y - 1.96 * sc.sem(TEST_DATA, axis=1))
tries = np.arange(0, len(y), 1.0)# each set is one try
plt.grid(True, alpha=0.5)
plt.gca().set_xlabel('Observation #')
plt.gca().set_ylabel('Mean (+- 95% CI)')
plt.title("Observations with corresponding 95% CI as error bar.")
plt.bar(tries, y, align='center', alpha=0.2)
plt.errorbar(tries, y, yerr=ci95, fmt=None)
plt.show()
#==============================================================================
# 8.6 使用文本和字体属性
#==============================================================================
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
#字体类型
families = ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace']
#字体大小
sizes = ['xx-small', 'x-small', 'small', 'medium', 'large',
'x-large', 'xx-large']
#字体风格
styles = ['normal', 'italic', 'oblique']
#字体粗细
weights = ['light', 'normal', 'medium', 'semibold', 'bold', 'heavy', 'black']
#字体的变体形式
variants = ['normal', 'small-caps']
fig = plt.figure(figsize=(9,17))
ax = fig.add_subplot(111)
ax.set_xlim(0,9)
ax.set_ylim(0,17)
# VAR: FAMILY, SIZE
y = 0
size = sizes[0]
style = styles[0]
weight = weights[0]
variant = variants[0]
for family in families:
x = 0
y = y + .5
for size in sizes:
y = y + .4
sample = family + " " + size
ax.text(x, y, sample,
family=family,
size=size,
style=style,
weight=weight,
variant=variant)
# VAR: STYLE, WEIGHT
y = 0
family = families[0]
size = sizes[4]
variant = variants[0]
for weight in weights:
x = 5
y = y + .5
for style in styles:
y = y + .4
print x, y
sample = weight + " " + style
ax.text(x, y, sample,
family=family,
size=size,
style=style,
weight=weight,
variant=variant)
ax.set_axis_off()
plt.show()
#==============================================================================
# 8.7 使用LaTeX渲染文本
#==============================================================================
import numpy as np
import matplotlib.pyplot as plt
# Example data
t = np.arange(0.0, 1.0 + 0.01, 0.01)
s = np.cos(4 * np.pi * t) * np.sin(np.pi*t/4) + 2
plt.rc('text', usetex=True)
plt.rc('font',**{'family':'sans-serif','sans-serif':['Helvetica'], 'size':16})
plt.plot(t, s, alpha=0.25)
# first, the equation for 's'
plt.annotate(r'$\cos(4 \times \pi \times {t}) \times \sin(\pi \times \frac {t} 4) + 2$', xy=(.9,2.2), xytext=(.5, 2.6), color='red', arrowprops={'arrowstyle':'->'})
# some math alphabet
plt.text(.01, 2.7, r'$\alpha, \beta, \gamma, \Gamma, \pi, \Pi, \phi, \varphi, \Phi$')
# some equation
plt.text(.01, 2.5, r'some equations $\frac{n!}{k!(n-k)!} = {n \choose k}$')
# more equations
plt.text(.01, 2.3, r'EQ1 $\lim_{x \to \infty} \exp(-x) = 0$')
# some ranges...
plt.text(.01, 2.1, r'Ranges: $( a ), [ b ], \{ c \}, | d |, \| e \|, \langle f \rangle, \lfloor g \rfloor, \lceil h \rceil$')
# you can multiply apples and oranges
plt.text(.01, 1.9, r'Text: $50 apples \times 100 oranges = lots of juice$')
plt.text(.01, 1.7, r'More text formatting: $50 \textrm{ apples} \times 100 \textbf{ apples} = \textit{lots of juice}$')
plt.text(.01, 1.5, r'Some indexing: $\beta = (\beta_1,\beta_2,\dotsc,\beta_n)$')
# we can also write on labels
plt.xlabel(r'\textbf{time} (s)')
plt.ylabel(r'\textit{y values} (W)')
# and write titles using LaTeX
plt.title(r"\TeX\ is Number "
r"$\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!",
fontsize=16, color='gray')
# Make room for the ridiculously large title.
plt.subplots_adjust(top=0.8)
plt.savefig('tex_demo')
plt.show()
#==============================================================================
# 8.8 理解pyplot和OO API的不同
#==============================================================================
import matplotlib.pyplot as plt
from matplotlib.path import Path
import matplotlib.patches as patches
# add figure and axes
fig = plt.figure()
ax = fig.add_subplot(111)
coords = [
(1., 0.), # start position
(0., 1.),
(0., 2.), # left side
(1., 3.),
(2., 3.),
(3., 2.), # top right corner
(3., 1.), # right side
(2., 0.),
(0., 0.), # ignored
]
line_cmds = [Path.MOVETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.LINETO,
Path.CLOSEPOLY,
]
# construct path
path = Path(coords, line_cmds)
# construct path patch
patch = patches.PathPatch(path, lw=1,
facecolor='#A1D99B', edgecolor='#31A354')
# add it to *ax* axes
ax.add_patch(patch)
ax.text(1.1, 1.4, 'Python', fontsize=24)
ax.set_xlim(-1, 4)
ax.set_ylim(-1, 4)
plt.show()