可视化的基本原理

在这里插入图片描述


一、为什么需要数据可视化?

无论是工作,学习,生活中都会遇到各种数据:年度预算数据,项目人力成本数据,实验记录数据,投资收益等等。当直接面对各种数据的时候,无法直观的反映出各种数据间的关系,因此就需要借助各种图表来对数据进行可视化的展示。
选择合理的数据图表,比用数据和文字描述更明了、更容易理解,将数据转换成图表的形式呈现,可以帮助我们更好地了解数据之间的关联关系及变化趋势,对问题的研究可以做出合理的推断和预测。
使用不同的图表从不同的方面来阐述问题,从不同的角度表现相对的关系、数据与数据之间的联系,从而寻找问题更好的解决方法。

举例,仅仅从下面的数据,无法直观的判断x和y之间的关系
在这里插入图片描述
但是从如下的图中,可以直观的看出x和y具有正相关。
在这里插入图片描述

二、matplotlib简介

matplotlib使用numpy进行数组运算,并调用一系列其他的Python库来实现硬件交互。matplotlib的核心是一套由对象构成的绘图API。它利用通用的图形用户界面工具包,如Tkinter, wxPython, Qt或GTK+,向应用程序嵌入式绘图提供了应用程序接口(API)。matplotlib是基于Python语言的开源项目,旨在为Python提供一个数据绘图包。matplotlib的对象体系严谨而丰富,为使用者提供了巨大的发挥空间。在熟悉了核心对象之后,可以轻易的定制图像。matplotlib的对象体系也是计算机图形学的一个优秀范例。
matplotlib最初由John D. Hunter撰写,它拥有一个活跃的开发社区,并且根据BSD样式许可证分发。 在John D. Hunter2012年去世前不久,Michael Droettboom被提名为matplotlib的主要开发者。

可以通过官网和源码可以更加深入的了解matplotlib。
官网:https://matplotlib.org
源码:https://github.com/matplotlib/matplotlib

三、 matplotlib 可视化的结构

使用matplotlib绘图,主要掌握figure(画布)、axes(坐标系)、axis(坐标轴)之间的关系。在matplotlib中,整个图像为一个Figure对象。在Figure对象中可以包含一个,或者多个axes对象。每个Axes对象都是一个拥有自己坐标系统的绘图区域。
如下图所示,在同一个figure画布中,存在四个坐标系,对应的每个坐标系都有各自的坐标轴。

举个比较形象的例子,一个画家需要创作一幅油画。首先需要在画框上固定一张画布上,有了画布就可以创作任意的作品了,这个过程就是matplotlib中初始化画布(figure);其次,需要规划在这个画布上的布局,是一整幅还是多个子图构成?如果是多了子图就需要为不同的的板块分配区域了,这个区域就对应了matplotlib中为不同的子图指定的坐标系(axes)。对应的画布中可能会存在1个或者多个坐标系;然后,在不同的子图创作完成之后,需要对边界进行勾勒,这个边界就对应了matplotlib中的坐标轴(axis).
在这里插入图片描述

四、matplotlib的构成

matplotlib官网上提供描述其结构的一张图,为了更方便的了解其内容将其中涉及到的内容增加了中文的说明。通过这张可以大致了解到通过绘制一张图所涵盖的部分。通过运行后面的

在这里插入图片描述

五、 示例代码

  • matplotlib图的构成:


import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import AutoMinorLocator, MultipleLocator, FuncFormatter

#支持中文
matplotlib.rcParams['font.family'] = ['Heiti TC']

np.random.seed(19680801)

X = np.linspace(0.5, 3.5, 100)
Y1 = 3+np.cos(X)
Y2 = 1+np.cos(1+X/0.75)/2
Y3 = np.random.uniform(Y1, Y2, len(X))

fig = plt.figure(figsize=(8, 8))
ax = fig.add_subplot(1, 1, 1, aspect=1)


def minor_tick(x, pos):
    if not x % 1.0:
        return ""
    return "%.2f" % x

#设置x轴主刻度的位置,主刻度标签设置为1的倍数
ax.xaxis.set_major_locator(MultipleLocator(1.000))
#设置x轴次刻度的位置,将每一个主刻度的区间等分为4格,如对应图中第一个主刻度区间中0.25,0.50,0.75
ax.xaxis.set_minor_locator(AutoMinorLocator(4))

#设置y轴主刻度的位置,主刻度标签设置为1的倍数
ax.yaxis.set_major_locator(MultipleLocator(1.000))
#设置y轴次刻度的位置,将每一个主刻度的区间等分为4格
ax.yaxis.set_minor_locator(AutoMinorLocator(4))

#设置x轴副刻度的文本显示格式
ax.xaxis.set_minor_formatter(FuncFormatter(minor_tick))

#设置x轴和y轴的显示区间
ax.set_xlim(0, 4)
ax.set_ylim(0, 4)


#设置主刻度中刻度的长宽属性
ax.tick_params(which='major', width=1.0)
ax.tick_params(which='major', length=10)

#设置次刻度的文本大小,颜色
ax.tick_params(which='minor', width=1.0, labelsize=10)
ax.tick_params(which='minor', length=5, labelsize=10, labelcolor='0.25')

#显示网格设置
ax.grid(linestyle="--", linewidth=0.5, color='.25', zorder=-10)

#按照y1,y2,y3来绘制
ax.plot(X, Y1, c=(0.25, 0.25, 1.00), lw=2, label="Blue signal", zorder=10)
ax.plot(X, Y2, c=(1.00, 0.25, 0.25), lw=2, label="Red signal")
ax.plot(X, Y3, linewidth=0,
        marker='o', markerfacecolor='w', markeredgecolor='k')

#设置图的标题
ax.set_title("Anatomy of a figure", fontsize=20, verticalalignment='bottom')
#设置x轴lable
ax.set_xlabel("X axis label")
#设置y轴lable
ax.set_ylabel("Y axis label")

#设置图例
ax.legend()


#通过patches和patheffects中的函数来绘制对应图中圆圈标注的地方
def circle(x, y, radius=0.15):
    from matplotlib.patches import Circle
    from matplotlib.patheffects import withStroke
    circle = Circle((x, y), radius, clip_on=False, zorder=10, linewidth=1,
                    edgecolor='black', facecolor=(0, 0, 0, .0125),
                    path_effects=[withStroke(linewidth=5, foreground='w')])
    ax.add_artist(circle)

#设置文本显示的属性
def text(x, y, text):
    ax.text(x, y, text, backgroundcolor="white",
            ha='center', va='top', weight='bold', color='blue')


#对各个标注点的显示
# Minor tick
circle(0.50, -0.10)
text(0.50, -0.32, "次刻度标签(Minor tick label)")

# Major tick
circle(-0.03, 4.00)
text(0.03, 3.80, "主刻度(Major tick)")

# Minor tick
circle(0.00, 3.50)
text(0.00, 3.30, "次刻度(Minor tick)")

# Major tick label
circle(-0.15, 3.00)
text(-0.15, 2.80, "主刻度标签(Major tick label)")

# X Label
circle(1.80, -0.27)
text(1.80, -0.45, "x轴标签(X axis label)")

# Y Label
circle(-0.27, 1.80)
text(-0.27, 1.6, "y轴标签(Y axis label)")

# Title
circle(1.60, 4.13)
text(1.60, 3.93, "名称(Title)")

# Blue plot
circle(1.75, 2.80)
text(1.75, 2.60, "线条(Line)\n(line plot)")

# Red plot
circle(1.20, 0.60)
text(1.20, 0.40, "线条(Line)\n(line plot)")

# Scatter plot
circle(3.20, 1.75)
text(3.20, 1.55, "节点样式(Markers)\n(scatter plot)")

# Grid
circle(3.00, 3.00)
text(3.00, 2.80, "网格(Grid)")

# Legend
circle(3.70, 3.80)
text(3.70, 3.60, "图例(Legend)")

# Axes
circle(0.5, 0.5)
text(0.5, 0.3, "坐标系(Axes)")

# Figure
circle(-0.3, 0.65)
text(-0.3, 0.45, "画布(Figure)")

color = 'blue'

#注解的显示,图中右下角spines
ax.annotate('坐标轴(Spines)', xy=(4.0, 0.35), xytext=(3.3, 0.5),
            weight='bold', color=color,
            arrowprops=dict(arrowstyle='->',
                            connectionstyle="arc3",
                            color=color))

ax.annotate('', xy=(3.15, 0.0), xytext=(3.45, 0.45),
            weight='bold', color=color,
            arrowprops=dict(arrowstyle='->',
                            connectionstyle="arc3",
                            color=color))

#文本的显示
ax.text(4.0, -0.4, "参考自官网的简介(\nMade with http://matplotlib.org)",
        fontsize=10, ha="right", color='.5')

#保存为图片
#fig.savefig('./img/AnatomyOfMatplotlib.png')
plt.show()

在这里插入图片描述

由于matplotlib对于中文显示的支持不太好,会导致中文显示为乱码。对于中文字符显示的解决方案会在后面进行说明

  • 多个子图的显示
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0.0,6.0)

figure,ax=plt.subplots(2,2,figsize=(16,9))

ax[0][0].plot(x,np.sin(np.pi*x));
ax[0][0].set_title("正弦")
ax[0][0].set_xlabel("时间")
ax[0][0].set_ylabel("幅度")
ax[0][0].set_ylabel("幅度")

ax[0][1].plot(x,np.cos(np.pi*x));
ax[0][1].set_title("余弦")
ax[0][1].set_xlabel("时间")
ax[0][1].set_ylabel("幅度")

ax[1][0].plot(x,np.log((x+1)*10));
ax[1][0].set_title("指数")
ax[1][0].set_xlabel("时间")
ax[1][0].set_ylabel("距离")


ax[1][1].plot(x,x*4);
ax[1][1].set_title("投资")
ax[1][1].set_xlabel("资金")
ax[1][1].set_ylabel("收益")

figure.tight_layout(pad=1.5)

在这里插入图片描述


一直计划去完成matplotlib系列的文章,但是拖延着很久都没有开始,从这篇文章作为一个新的开始去完成之前很久的计划。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值