Python数据可视化matplotlib:第二回:艺术画笔见乾坤

第二回:艺术画笔见乾坤

在这里插入图片描述

Artist的分类

这一部分主要介绍的是Artist内部的一些东西。下面内容转载自fantastic-matplotlib

第一列表示matplotlib中子图上的辅助方法,可以理解为可视化中不同种类的图表类型,如柱状图,折线图,直方图等,这些图表都可以用这些辅助方法直接画出来,属于更高层级的抽象。

第二列表示不同图表背后的artist类,比如折线图方法plot在底层用到的就是Line2D这一artist类。

第三列是第二列的列表容器,例如所有在子图中创建的Line2D对象都会被自动收集到ax.lines返回的列表中。

Axes helper methodArtistContainer
bar - bar chartsRectangleax.patches
errorbar - error bar plotsLine2D and Rectangleax.lines and ax.patches
fill - shared areaPolygonax.patches
hist - histogramsRectangleax.patches
imshow - image dataAxesImageax.images
plot - xy plotsLine2Dax.lines
scatter - scatter chartsPolyCollectionax.collections

上表清晰的介绍了常用的绘图方法对应的Artist类中的对象和容器。

1. 基本元素primitives
1.1 2DLines

如何获取Lines2D对象

code1 从plot绘制方法中获取:

# 1. plot方法绘制
x = range(0,5)
y1 = [2,5,7,8,10]
y2= [3,6,8,9,11]

fig,ax= plt.subplots()
ax.plot(x,y1)
ax.plot(x,y2)
print(ax.lines); # 通过直接使用辅助方法画线,打印ax.lines后可以看到在matplotlib在底层创建了两个Line2D对象

在这里插入图片描述

code2 直接创建lines2D对象:

# 2. Line2D对象绘制

x = range(0,5)
y1 = [2,5,7,8,10]
y2= [3,6,8,9,11]
fig,ax= plt.subplots()
lines = [Line2D(x, y1), Line2D(x, y2,color='orange')]  # 显式创建Line2D对象
for line in lines:
    ax.add_line(line) # 使用add_line方法将创建的Line2D添加到子图中
ax.set_xlim(0,4)
ax.set_ylim(2, 11);

在这里插入图片描述

图形绘制完成后我又分别打印出来两种线对象的类型,可以看见是一致的,虽然plot绘制过程中没有显示创建Lines2D对象,但其实绘图区中的线都是Lines2D对象,虽然平时常用的都是ptplot来绘制图像,但是也要知道其底层对象是由哪些构成的。
在这里插入图片描述

设置Line2D属性的三种方法
下面三种方法中,最常用也是最简单的就是第一种方法,在绘制图形的时候设置其对应的参数属性,不需要单独获取对象再来设置。再这些属性设置中有许多可以选择的参数,具体的颜色参数,形状参数等均可通过查官方文档获得详细说明。

下图是官方文档中关于linestyles这部分属性的可选参数:
在这里插入图片描述

code1:直接在plot()函数中设置相应参数

# 套用第一回的通用模板
# 设置Line2D属性方法一

# step1 准备数据
x = range(0, 5)
y = [2, 5, 7, 8, 10]

# step2 由于这部分是设置Line2D属性 这部分在下面代码中会有体现


# step3 定义布局
fig, ax = plt.subplots()  

# step4 绘制图像
ax.plot(x, y, label='linear', linewidth = 10, linestyle = 'dashed')  

# step5 添加标签,文字和图例
ax.set_xlabel('x label') 
ax.set_ylabel('y label') 
ax.set_title("Simple Plot")  
ax.legend() 

在这里插入图片描述

code2: 对线对象进行设置

# 设置Line2D属性方法二

# step1 准备数据
x = range(0, 5)
y = [2, 5, 7, 8, 10]

# step2 对线对象进行属性设置
line, = plt.plot(x, y, label='linear', color = 'g', linewidth = 7, linestyle = 'dotted')
line.set_antialiased(False) # 关闭抗锯齿功能
plt.show() 

在这里插入图片描述

code3: 获得线属性,使用setp()函数设置:

# 设置Line2D属性方法三

# step1 准备数据
x = range(0, 5)
y = [2, 5, 7, 8, 10]

# step2 对线对象进行属性设置
line = plt.plot(x, y)
plt.setp(line, color = 'pink', linewidth = 12)
plt.show() 

在这里插入图片描述

1.2 errorbar

pyplot里有个专门绘制误差线的功能,通过errorbar类实现,查看了一下其相关参数,比较有意思的是其中fmt参数,第一眼看就感觉很熟悉,很类似输出语句当中的format的缩写,这个参数也是用于控制折线图中某个点的颜色,形状,线条风格。文档中示例的’co–’,其中c代表颜色,o代表点的形状,最后一部分表示线条风格。不像别的绘图方法,这里使用一个参数来控制输出格式,但是像plot里面会分别使用linestyle,color,marker,linewidth, markersize等控制输出格式。然后我就去查了一下官方文档里面的plot相关参数,发现是这样的:
在这里插入图片描述
看起来好像这些参数实在**kwargs中,但是再往下一看,我发现了这:
在这里插入图片描述
原来这部分在plot参数里面也是fmt,下面我就随便改了一下参数试了一下,需要注意的是fmt中颜色那个参数只识别第一个字符为颜色参数,也就是说,这里只能使用有颜色缩写的那部分颜色。

fig = plt.figure()
x = np.arange(10)
y = 2.5 * np.sin(x / 20 * np.pi)
yerr = np.linspace(0.05, 0.2, 10)
plt.errorbar(x, y + 3, yerr=yerr, fmt = 'b*--', ecolor = 'r', label='both limits (default)')
plt.legend(loc = "upper left")

在这里插入图片描述

接下来下面就是常见的直方图,柱状图,饼图
关于这几种图的绘制基本都可以使用第一回中的两种方式来绘制,但简单且常用的还是日常中的pyplot模块中的绘制方式。这部分网上资料很多我在这里就不多加赘述。

2. 容器 container

这里的容器指的就是第一回中所讲述到的那几种容器,自上而下分别是,Figure容器, Axes容器,Axis容器,Tick容器,这些容器构成了整个绘图区域的大框架。

  1. Figure容器时整个绘图区域最大的部分,他创建的是一个大的rectangle来存放绘图区域,可以在面添加一个个子图来实现多图显示.
  2. Axes容器用于存放Artist类中元素,绘制具体的相应图形。
  3. Axis容器主要处理坐标轴上的刻度线、刻度label、坐标网格、坐标轴标题
  4. Tick容器和Axis同属于matplotlib.axis模块,是从Figure到Axes到Axis到Tick中最末端的容器对象。Tick容器可以更细致的实现对坐标轴,网格线等对象的处理。

思考题

  1. primitives 和 container的区别和联系是什么,分别用于控制可视化图表中的哪些要素?
    primitives和container的联系就是primitives是属于container内部的许多细节控制。
    primitive是基本要素,它包含一些我们要在绘图区作图用到的标准图形对象,如曲线Line2D,文字text,矩形Rectangle,图像image等;
    container是容器,即用来装基本要素的地方,包括图形figure、坐标系Axes和坐标轴Axis。
    • 使用提供的drug数据集,对第一列yyyy和第二列state分组求和,画出下面折线图。PA加粗标黄,其他为灰色。
      图标题和横纵坐标轴标题,以及线的文本暂不做要求。


code:

# 导入数据集
data = pd.read_csv('../data/Drugs.csv')
plt.rcParams['axes.facecolor']='lightgrey'
# 获取横坐标值
labels = list(set(data['YYYY']))

# 获取每条线值
data_VA = data[data['State'] == 'VA'].groupby('YYYY').sum()
data_WV = data[data['State'] == 'WV'].groupby('YYYY').sum()
data_PA = data[data['State'] == 'PA'].groupby('YYYY').sum()
data_OH = data[data['State'] == 'OH'].groupby('YYYY').sum()
data_KY = data[data['State'] == 'KY'].groupby('YYYY').sum()

# 绘图
plt.figure(figsize = (18,12))
plt.plot(data_VA, color = 'gray')
plt.plot(data_WV, color = 'gray')
plt.plot(data_PA, color = 'orange', linewidth = 8)
plt.plot(data_OH, color = 'gray')
plt.plot(data_KY, color = 'gray')
plt.grid(color = 'white')
plt.xlabel('Year', fontsize = 12)
plt.ylabel('DrugReports', fontsize = 12)
plt.title('Evolution of PA  vs other state', loc = 'left', color = 'orange', fontsize = 20)
plt.annotate(r'$VA$',xy=(2017,data_VA.iloc[-1][0]),xycoords='data',xytext=(+5,-5),
             textcoords='offset points',fontsize=10, color = 'gray')
plt.annotate(r'$WV$',xy=(2017,data_WV.iloc[-1][0]),xycoords='data',xytext=(+5,-5),
             textcoords='offset points',fontsize=10, color = 'gray')
plt.annotate(r'$PA$',xy=(2017,data_PA.iloc[-1][0]),xycoords='data',xytext=(+5,-5),
             textcoords='offset points',fontsize=10, color = 'orange')
plt.annotate(r'$OH$',xy=(2017,data_OH.iloc[-1][0]),xycoords='data',xytext=(+5,-5),
             textcoords='offset points',fontsize=10, color = 'gray')
plt.annotate(r'$KY$',xy=(2017,data_KY.iloc[-1][0]),xycoords='data',xytext=(+5,-5),
             textcoords='offset points',fontsize=10, color = 'gray')

plt.show()

在这里插入图片描述
3. - 分别用一组长方形柱和填充面积的方式模仿画出下图,函数 y = -1 * (x - 2) * (x - 8) +10 在区间[2,9]的积分面积

** code1: **

plt.rcParams['axes.facecolor']='white'
# 绘制函数曲线
fig = plt.figure(figsize = (18,12))
ax = fig.add_subplot(111)
x = np.linspace(0, 10, 50)
y = -1 * (x - 2) * (x - 8) +10
ax.plot(x, y, color = 'red')


# 创建矩阵类,用于填充
for i in x:
    if i >= 2 and i <= 9:
        rect =  plt.Rectangle((i,0),0.1,-1 * (i - 2) * (i - 8) +10, color = 'lightgrey')
        ax.add_patch(rect)
ax.set_xlim(-1, 12)
ax.set_ylim(0, 20)
plt.show()

在这里插入图片描述

code2:

x = np.linspace(0, 10, 50)
y = -1 * (x - 2) * (x - 8) +10
plt.figure(figsize = (18,12))
x1 = []
for i in x:
    if i >= 2 and i <= 9:
        x1.append(i)
x1 = np.array(x1)
y1 = -1 * (x1 - 2) * (x1 - 8) +10
x1 = np.insert(x1, 0, 2)
x1 = np.append(x1, 9)
y1 = np.insert(y1, 0, 0)
y1 = np.append(y1, 0)


plt.plot(x, y, color = 'red')
plt.fill(x1, y1, color = "grey", alpha = 0.3);
plt.xlim(-1, 12)
plt.ylim(0, 20)

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值