【Python数据可视化(七)】使用正确的图表理解数据

对数图

  根据一般经验,遇到一下情况应该使用对数标度:当要展示的数据的值跨越好几个量级时;当要展示的数据有朝向大值(一些数据点比其他数据大很多)的倾斜度时;当要展示变化率,而不是值的变化。但是不要盲目地遵循这些规则,它们更像是指导,而不是规则。

from matplotlib import pyplot as plt
import numpy as np

# 生成两个简单的数据集合:指数/对数y和线性z
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))
# 创建一个包含四个子区的图形
# 创建两个包含数据集合y的子区:一个为对数标度,一个线性标度
# y = 10exp(lg(10^x))
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')

# 创建两个包含数据集合z的子区:一个为对数标度,一个为线性标度
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()

在这里插入图片描述

频谱图

  频谱图是一个随时间变化的谱表现,它显示了信号的频谱强度随时间的变化。频谱图是把声音或者其他信号的频谱以可视化的方式呈现出来。它被用于在很多科学领域,从声音指纹识别到雷达工程学和地震学。
  通常,频谱图的布局如下:x轴表示时间,y轴表示频率,第三个维度是频率-时间对的幅值,通过颜色表示。因为这是三维的数据,因此也可以创建3D图表来表示,其中强度表示z轴上的高度。
  这是使用预录制的声音文件test.wav,也可使用下面的代码自己生成一个样本。

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)

    # 增加高音信号的间隔
    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)

    # 可以直观地看到
    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()

在这里插入图片描述

 &esmp;补充说明:
  顶部的图形是生成的信号。x表示时间,y表示信号的幅值。底部的图形是相同的信号在频率域中的呈现。这里x轴表示时间,y轴表示信号的频率。

  音频文件的声音波形图如下:

import wave
import matplotlib.pyplot as plt
import numpy as np


def read_wav_data(filename):
    '''
    读取一个wav文件,返回声音信号的时域谱矩阵和播放时间
    '''

    wav = wave.open(filename, "rb")  # 打开一个wav格式的声音文件流
    num_frame = wav.getnframes()  # 获取帧数
    num_channel = wav.getnchannels()  # 获取声道数
    framerate = wav.getframerate()  # 获取帧速率
    num_sample_width = wav.getsampwidth()  # 获取实例的比特宽度,即每一帧的字节数
    str_data = wav.readframes(num_frame)  # 读取全部的帧
    wav.close()  # 关闭流
    wave_data = np.frombuffer(str_data, dtype=np.short)  # 将声音文件数据转换为数组矩阵形式
    wave_data.shape = -1, num_channel  # 按照声道数将数组整形,单声道时候是一列数组,双声道时候是两列的矩阵
    wave_data = wave_data.T  # 将矩阵转置
    wave_data = wave_data
    return wave_data, framerate


def wav_show(wave_data, fs):  # 显示出来声音波形
    time = np.arange(0, len(wave_data)) * (1.0 / fs)  # 计算声音的播放时间,单位为秒

    # 画声音波形
    plt.plot(time, wave_data)
    plt.show()

    # if (__name__ == '__main__'):
    #     wave_data, fs = read_wav_data("1.wav")
    #     wav_show(wave_data[0], fs)
    #     wav_show(wave_data[1], fs)  # 如果是双声道则保留这一行,否则删掉这一行

if __name__ == '__main__':

    wd, fs = read_wav_data('test.wav')
    wav_show(wd[0], fs)

在这里插入图片描述

  频谱图:

import wave
import struct
from scipy import *
from pylab import *

filename = 'test.wav'
wavefile = wave.open(filename, 'r')  # open for writing

# 读取wav文件的四种信息的函数。期中numframes表示一共读取了几个frames,在后面要用到滴。
nchannels = wavefile.getnchannels()
sample_width = wavefile.getsampwidth()
framerate = wavefile.getframerate()
numframes = wavefile.getnframes()

print("channel", nchannels)
print("sample_width", sample_width)
print("framerate", framerate)
print("numframes", numframes)

# 建一个y的数列,用来保存后面读的每个frame的amplitude。
y = zeros(numframes)

# for循环,readframe(1)每次读一个frame,取其前两位,是左声道的信息。右声道就是后两位啦。
# unpack是struct里的一个函数,用法详见http://docs.python.org/library/struct.html。简单说来就是把#packed的string转换成原来的数据,无论是什么样的数据都返回一个tuple。这里返回的是长度为一的一个
# tuple,所以我们取它的第零位。
for i in range(numframes):
    val = wavefile.readframes(1)
    left = val[0:2]
    # right = val[2:4]
    v = struct.unpack('h', left)[0]
    y[i] = v

# framerate就是44100,文件初读取的值。然后本程序最关键的一步!specgram!实在太简单了。。。
Fs = framerate
specgram(y, NFFT=1024, Fs=Fs, noverlap=900)
show()

在这里插入图片描述

创建火柴杆图

  一个二维的火柴图(stem plot)把数据显示为沿x轴的基线延伸的线条。圆圈(默认值)或者其他标记表示每个杆的结束,其y轴表示了数据值。不要把火柴杆图和茎叶图(stem and leaf plot)混淆,茎叶图是把不重要的数值表示为叶,把较高位的值表示为茎的一种数据表方法。
  普通的线形图无法用来展示这种离散的数据,使用离散值序列来绘制火柴杆图。绘制离散序列为杆,数据值表示为每个杆末端的标记。杆从基线(通常在y=0处)延伸到数据点的值。
  火柴杆图配置有以下一些格式器

linefmt杆线的线条格式器
markerfmt火柴杆线条末端的标记用该参数格式化
basefmt规定基线的外观
label设置火柴杆图图例的标签
hold把所有当前图形放在当前坐标轴上
bottom在y轴方向设置基线位置,默认值为0
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 -保持当前轴进一步绘制
# False-清晰并使用新的图标/图
hold = False
label = 'delta'
markerline, stemlines, baseline = plt.stem(x, y, bottom=bottom,
                                           label=label)
# 使用setp()进行设置由stem()生成线条的多个属性
plt.setp(markerline, color='red', marker='o')
plt.setp(stemlines, color='blue', linestyle=':')
plt.setp(baseline, color='grey', linewidth=2, linestyle='-')
plt.legend()
plt.show()

在这里插入图片描述

绘制矢量场流线图

  流线图被用来可视化矢量场的流态。科学和自然学科上的一些例子包括磁场、万有引力和流体运动。矢量场可以通过以每个点指定一个线条和一个或多个箭头的方式可视化出来。强度可以用线条长度表示,方向由指向特定方向的箭头表示。用matplotlib.pyplot.streamplot函数来可视化矢量场,该函数重要的参数是(X,Y),是一个一维Numpy数组的等距网格。(U,V)参数匹配的是(X,Y)速率的二维Numpy数组。U和V矩阵在维度上的行数必须等于Y的长度,列的数量必须匹配X的长度。

import matplotlib.pyplot as plt
import numpy as np
Y,X=np.mgrid[0:5:100j,0:5:100j]
U = X
V=Y
plt.streamplot(X,Y,U,V)
plt.show()

在这里插入图片描述

绘制风杆(barbs)

  风杆是风速和风向地一种表现形式,主要由气象学家使用。理论上讲,可以被用来可视化任何类型地二维向量。它们和箭头类似,但不同地是通过箭头地长度表示向量地大小,而风杆通过把直线或者三角形作为大小增量提供了更多关于向量大小的信息。下面是一组典型地风杆:

import matplotlib.pyplot as plt
import numpy as np

# 定义风由南至北的速度,以海里/小时为单位
V = [0, -5, -10, -15, -30, -40, -50, -60, -100]

# 帮助与V向量的大小协调的其他值的大小
SIZE = len(V)

# 定义风在东西方向的速度,“水平”速度分量是0
U = np.zeros(SIZE)

# 经度、纬度;定义的线性分布水平方式的风杆,以指出速度增加
y = np.ones(SIZE)
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)
X, Y = np.meshgrid(x, y)
U, V = X + 25, Y - 35
plt.subplot(1, 2, 1)
plt.barbs(X, Y, U, V, flagcolor='green', alpha=0.75)
plt.grid(True, color='gray')
plt.subplot(1, 2, 2)
plt.quiver(X, Y, U, V, facecolor='red', alpha=0.75)
plt.grid(True, color='grey')
plt.show()

在这里插入图片描述

使用颜色表

 &emp;如果数据没有与红色/绿色有很强的关联时,要尽可能地避免使用这两种颜色。颜色表一般可以归为以下几类:

Sequential亮度单调递减。这表示同一颜色从低饱和度到高饱和度地两个色调地单色颜色表,例如白色到天蓝色。
Diverging中间亮度最高,向两端递减。
Qualitative不同种类地颜色用来区分不同的数据类型。对于数据没有固定地顺序,并且想要让不同种类地数据之间能轻易地区分开地情况,可以选用该颜色表。
Cyclic当数据可以围绕端点值显示地时候,用该颜色表非常方便,例如表示一天地时间、风向或者相位角。
brg一个发散型的蓝-红-绿颜色表
bwr发散型的蓝-白-红颜色表
coolwarm对于3D阴影,色盲和颜色排序非常有用
rainbow发散亮度的紫-蓝-绿-黄-橙-红光谱颜色表
seismic发散型蓝-白-红颜色表
terrain表示地图标记的颜色(蓝,绿,黄,棕和白),最初来自IGOR Pro软件
  这里展示的大多数颜色表可以通过在颜色表名字后面加上_r后缀进行反转,例如hot_r是反向循环的hot颜色表。
import matplotlib.pyplot as plt

print(plt.colormaps())
import numpy as np

# 十六进制格式的diverging颜色表颜色值
red_yellow_green = ['#d73027', '#f46d43', '#fdae61',
                    '#fee08b', '#ffffbf', '#d9ef8b',
                    '#a6d96a', '#66bd63', '#1a9850'
                    ]
sample_size = 1000
fig, ax = plt.subplots(1)
for i in range(9):
    # 生成随机样本x和y
    y = np.random.normal(size=sample_size).cumsum()
    x = np.arange(sample_size)
    ax.scatter(x, y, label=str(i), linewidth=0.1, edgecolors='grey',
               facecolor=red_yellow_green[i])
ax.legend()
plt.show()

在这里插入图片描述

使用散点图和直方图

  两个数据点之间的理想的正相关为1,理想的负相关为-1.所有在此区间内的值表示两个值之间存在较弱的相关性。通常,从两个变量的真正关联的角度看,在-0.5~0.5之间的值被认为是没有价值的。

import matplotlib.pyplot as plt
import numpy as np

# 使用一个干净的数据集合
from ch07_search_data import DATA

d = DATA

# 使用一个相同长度(365个数据点)的随机正态分布作为数据集合的d1
d1 = np.random.random(365)
assert len(d) == len(d1)

fig = plt.figure()
# 创建4个子区的图表
# 第一个子区绘制d和d1的散点图
ax1 = fig.add_subplot(221)
ax1.scatter(d, d1, alpha=0.5)
ax1.set_title('No correlation')
ax1.grid(True)
# 在第二个子区,绘制d1和d1的散点图
ax2 = fig.add_subplot(222)
ax2.scatter(d1, d1, alpha=0.5)
ax2.set_title('Ideal positive correlation')
ax2.grid(True)
# 在第三个子区绘制d1和反序d1的散点图
ax3 = fig.add_subplot(223)
ax3.scatter(d1, d1 * -1, alpha=0.5)
ax3.set_title('Ideal negative correlation')
ax3.grid(True)
# 在第四个子区,绘制d1和由d1和d组合而成的数据集合的散点图
ax4 = fig.add_subplot(224)
ax4.scatter(d1, d1 + d, alpha=0.5)
ax4.set_title('Non ideal positive correlation')
ax4.grid(True)

plt.tight_layout()

plt.show()

在这里插入图片描述
  也可以给散点图添加直方图,通过这种方式能了解更多所绘制的数据的信息,可以添加水平直方图和垂直直方图来显示在x轴和y轴上数据点的频率,通过这种方法,可以同时看到整个数据集合的汇总信息(直方图)和每一个数据点(散点图)。

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)

    # compute bins accordingly
    binwidth = 0.25

    # 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)

在这里插入图片描述

绘制两个变量间的互相关图形

import matplotlib.pyplot as plt
import numpy as np

# 导入数据
from ch07_search_data import DATA

d = DATA

total = sum(d)
av = total / len(d)
z = [i - av for i in d]

# 生成同一时间段的随机数据
d1 = np.random.random(365)
assert len(d) == len(d1)

total1 = sum(d1)
av1 = total1 / len(d1)
z1 = [i - av1 for i in d1]

fig = plt.figure()

ax1 = fig.add_subplot(311)
ax1.plot(d)
ax1.set_xlabel('Google Trends data for "flowers"')

ax2 = fig.add_subplot(312)
ax2.plot(d1)
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()

在这里插入图片描述

自相关地重要性

  自相关表示在一个给定地时间序列或一个连续地时间间隔上其自身的延迟(也就是时间上地延迟版本之间地相似度)。它发生在一个时间序列研究中,指在一个给定地时间周期内地错误在未来地时间周期上继续存在。

import matplotlib.pyplot as plt
import numpy as np

from ch07_search_data import DATA as d

total = sum(d)
av = total / len(d)
z = [i - av for i in d]
fig = plt.figure()

ax1 = fig.add_subplot(221)
ax1.plot(d)
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')

d1 = np.random.random(365)
assert len(d) == len(d1)

total = sum(d1)
av = total / len(d1)
z = [i - av for i in d1]

ax3 = fig.add_subplot(223)
ax3.plot(d1)
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()

在这里插入图片描述

绘制甘特图

  甘特图是一种广泛使用地基于时间数据地可视化方式。基本的甘特图在x轴上有一个时间序列,在y轴上有一些表示任务或者子任务地标签。任务持续时间通常被可视化为一条线段或者一个柱状图表,从给定任务地开始时间延伸到其结束时间。如果存在子任务,一个或者多个子任务有一个父任务,在这种情况下,人物的总时间是所有子任务的时间之和,在计算时,重叠的时间和间隔时间都算在内。这在执行关键路径分析时非常有用。

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):
    '''
    简单地的线条渲染器
    '''

    # 红黄绿散色图
    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):
        '''
        将*date_string*的字符串表示格式设置为*matplotlib日期*实例。
        '''
        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):
        '''
        处理每个任务并将barh添加到当前的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'''
        # make x axis date 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):
        '''
        对于给定的*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()

在这里插入图片描述

使用文本和字体属性

  基本的文本操作,以及它们在matplotlib OO API对应的函数。

matplotlib.pyplotMatplotlib API描述
textmatplotlib.axes.Axes.text在指定的位置(x,y)为坐标轴添加文本。fontdict参数允许覆盖一般的字体属性,或者可以使用kwargs覆盖特定的属性
xlabelmatplotlib.axes.Axes.set_xlabel设置x轴的标签。通过labelpad指定标签和x坐标轴之间的间隔
ylabelmatplotlib.axes.Axes.set_ylabel同上,用于y轴
titlematplotlib.axes.Axes.set_title设置坐标轴的标题。接受所有一般的文本属性,如fontdict和kwargs
suptitlematplotlib.figure.Figure.suptitle为图表添加一个居中的标题。通过kwargs接受所有通用文本的属性。使用Figure坐标
figtextmatplotlib.figure.Figure.text在图表的任意位置添加文本。位置通过x,y定义,使用图表的归一化坐标。使用fontdict覆盖字体属性,但也支持使用kwargs覆盖任何文本相关的属性
  matplotlib.text.Text实例支持的字体属性见下表:
属性描述
family指定字体名称或字体类型。如果是一个列表,那么按优先级顺序排列,这样将使用第一个匹配的字体名称
size或者fontsize指定字体的相对大小或者绝对点数,或者指定字体的相对大小为一个大小字符串
style或者fontstyle指定字体风格为一个字符串
variant指定字体的变体形式
weight或fontweight指定字体粗细或者使用一个特定的粗细字符串。字体粗细定义为相对于字体高度的字符轮廓厚度
stretch或fontstretch指定字体的拉伸。拉伸定义为水平的压缩或者扩张。
fontproperties规范字体属性
import matplotlib.pyplot as plt

# 字体类型和大小
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)
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)

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
        sample = weight + " " + style
        ax.text(x, y, sample,
                family=family,
                size=size,
                style=style,
                weight=weight,
                variant=variant)
# 去掉坐标轴
ax.set_axis_off()
plt.show()

在这里插入图片描述

用LaTeX渲染文本

import numpy as np
import matplotlib.pyplot as plt


# 生成样本数据
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
# 对于当前绘图项目,设置matplotlib使用LaTeX
plt.rc('text', usetex=True)
# 设置使用的字体和字体属性
plt.rc('font',**{'family':'sans-serif','sans-serif':['Helvetica'], 'size':16})

plt.plot(t, s, alpha=0.25)

# 添加注释,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':'->'})

# 演示希腊符号语法
plt.text(.01, 2.7, r'$\alpha, \beta, \gamma, \Gamma, \pi, \Pi, \phi, \varphi, \Phi$')
# 等式语法 分数
plt.text(.01, 2.5, r'some equations $\frac{n!}{k!(n-k)!} = {n \choose k}$')
# 极限和指数
plt.text(.01, 2.3, r'EQ1 $\lim_{x \to \infty} \exp(-x) = 0$')
# 范围表达式
plt.text(.01, 2.1, r'Ranges: $( a ), [ b ], \{ c \}, | d |, \| e \|, \langle f \rangle, \lfloor g \rfloor, \lceil h \rceil$')
# 带文本和格式化文本的表达式
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},,\beta_{n})$')
# 在轴标签上写上数学表达式
plt.xlabel(r'\textbf{time} (s)')
plt.ylabel(r'\textit{y values} (W)')
# 标题
plt.title(r"\TeX\ is Number "
          r"$\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!",
          fontsize=16, color='gray')
# 为大得离谱的标题腾出空间
plt.subplots_adjust(top=0.8)
plt.savefig('tex_demo')
plt.show()

在这里插入图片描述

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZoomToday

给作者倒一杯卡布奇诺

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值