zoukankan      html  css  js  c++  java
  • python绘图专题(matplotlib,Pandas DataFrame)

    Matplotlib绘图

    user guide: https://matplotlib.org/users/index.html
    官方教程:https://www.matplotlib.org.cn/tutorials/
    其它教程:https://www.runoob.com/w3cnote/matplotlib-tutorial.html

    Matplotlib参数工作逻辑:

    figure是放置图表的容器,axes是坐标系,默认情况下,一张纸(figure)被 1个图表(axes)占满
    matplotlib里有三个概念:轴-axis,刻度-tick,标签-label,通常我们的操作都是基于axes,因为我们在操作整个图表

    图表主要元素的函数说明

    函数 核心参数 功能
    figure() figsize:图表尺寸,dpi:分辨率 设置图像的大小和分辨率
    title() str:图表名称,fontdict:文本格式/字体大小/类型 设置标题
    xlabel(),ylabel() xlabel:X轴名,ylabel:Y轴名 设置X/Y轴的标题
    axis(),xlim(),ylim() xmin,xmax或ymin,ymax 设置X/Y轴的范围
    xticks(),yticks() ticks:刻度数值,labels:刻度名称,fontdict 设置X/Y轴的刻度
    grid() b:有无网格,which:主次网格,axis:X/Y轴网格线,color,linestyle,linewidth,alpha:透明度 设置X/Y轴的主要和次要网格线
    legend() loc:位置,edgecolor,facecolor,fontsize 控制图例显示

    常见图表类型

    ID 图表类型 函数 核心参数
    1 折线图 plot()
    2 散点图/汽泡图 scatter()
    3 柱形图/堆积柱形图 bar()
    4 条形图/规程条形图 barh
    5 面积图 fill_between
    6 堆积面积图/量化波形图 stackplot
    7 饼图 pie()
    8 误差棒 errorbar
    9 统计直方图 hist()
    10 箱形图 boxplot()
    11 垂直X轴直线/垂直Y轴直线 axhline(),axvline()
    12 垂直X轴矩形/垂直Y轴矩形 axhspan(),axvspan()
    13 指定位置文本 text()
    14 指定数据点标注 annotate()

    plt.setp(对象)查看对象可设置的属性 --一个好用的入门方法

    plt.setp本身也是一种快速批量修改属性的方法,可以查看axes的众多属性

    plt.setp(axes)

    plt.setp(axes)
      adjustable: {'box', 'datalim'}
      agg_filter: a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array
      alpha: float or None
      anchor: 2-tuple of floats or {'C', 'SW', 'S', 'SE', ...}
      animated: bool
      aspect: {'auto'} or num
      autoscale_on: bool
      autoscalex_on: bool
      autoscaley_on: bool
      axes_locator: Callable[[Axes, Renderer], Bbox]
      axisbelow: bool or 'line'
      box_aspect: None, or a number
      clip_box: `.Bbox`
      clip_on: bool
      clip_path: Patch or (Path, Transform) or None
      contains: unknown
      facecolor or fc: color
      figure: `.Figure`
      frame_on: bool
      gid: str
      in_layout: bool
      label: object
      navigate: bool
      navigate_mode: unknown
      path_effects: `.AbstractPathEffect`
      picker: None or bool or callable
      position: [left, bottom, width, height] or `~matplotlib.transforms.Bbox`
      prop_cycle: unknown
      rasterization_zorder: float or None
      rasterized: bool or None
      sketch_params: (scale: float, length: float, randomness: float)
      snap: bool or None
      subplotspec: unknown
      title: str
      transform: `.Transform`
      url: str
      visible: bool
      xbound: unknown
      xlabel: str
      xlim: (bottom: float, top: float)
      xmargin: float greater than -0.5
      xscale: {"linear", "log", "symlog", "logit", ...}
      xticklabels: unknown
      xticks: unknown
      ybound: unknown
      ylabel: str
      ylim: (bottom: float, top: float)
      ymargin: float greater than -0.5
      yscale: {"linear", "log", "symlog", "logit", ...}
      yticklabels: unknown
      yticks: unknown
      zorder: float
    
    

    以上属性,获取的方式是:axes.get_xticklabels(),即使用“前缀+下划线+属性名”来调用。
    也可以再查看它的子属性,如plt.setp(axes.get_xticklabels())或plt.setp(axes.get_xticklabels()[0]),但是不是每个子属性都可以用plt.setp()查看下去的。

    再比如:

    plt.setp(fig)

    plt.setp(fig)
      agg_filter: a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array
      alpha: float or None
      animated: bool
      canvas: FigureCanvas
      clip_box: `.Bbox`
      clip_on: bool
      clip_path: Patch or (Path, Transform) or None
      constrained_layout: bool or dict or None
      constrained_layout_pads: unknown
      contains: unknown
      dpi: float
      edgecolor: color
      facecolor: color
      figheight: float
      figure: `.Figure`
      fig float
      frameon: bool
      gid: str
      in_layout: bool
      label: object
      path_effects: `.AbstractPathEffect`
      picker: None or bool or callable
      rasterized: bool or None
      size_inches: (float, float) or float
      sketch_params: (scale: float, length: float, randomness: float)
      snap: bool or None
      tight_layout: bool or dict with keys "pad", "w_pad", "h_pad", "rect" or None
      transform: `.Transform`
      url: str
      visible: bool
      zorder: float
    

    以上的这些属性,我们会在后面用到。
    面向对象设计,意味着图表上能看到的对象都有一个对象代表它,matplotlib的灵活在于对细节的控制。

    查看自定义对象的属性(非常重要!)

    通过查看自定义对象的属性, 可以方便修改,举个简单的例子:

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    df = pd.DataFrame({'year':[1565,1570,1575,1580,1585],'wheat':[41,45,42,49,41.5],'wages':[5,5.05,5.08,5.12,5.15]})
    df.year = df.year.astype(str)
    
    fig,axes = plt.subplots()
    fig.set_figwidth(20)
    fig.set_figheight(10)
    bar = axes.bar(df.year,df.wheat)
    

    这里定义了 bar, 它是一个 <BarContainer object of 5 artists>
    为了修改它, 我们可以用plt.setp(bar)来查看它的属性。

    plt.setp(bar)
      agg_filter: a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array
      alpha: float or None
      animated: bool
      antialiased or aa: unknown
      bounds: (left, bottom, width, height)
      capstyle: {'butt', 'round', 'projecting'}
      clip_box: `.Bbox`
      clip_on: bool
      clip_path: Patch or (Path, Transform) or None
      color: color
      contains: unknown
      edgecolor or ec: color or None or 'auto'
      facecolor or fc: color or None
      figure: `.Figure`
      fill: bool
      gid: str
      hatch: {'/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*'}
      height: unknown
      in_layout: bool
      joinstyle: {'miter', 'round', 'bevel'}
      label: object
      linestyle or ls: {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}
      linewidth or lw: float or None
      path_effects: `.AbstractPathEffect`
      picker: None or bool or callable
      rasterized: bool or None
      sketch_params: (scale: float, length: float, randomness: float)
      snap: bool or None
      transform: `.Transform`
      url: str
      visible: bool
       unknown
      x: unknown
      xy: (float, float)
      y: unknown
      zorder: float
    

    知道了它的属性,我们就能方便的对它进行操作。具体内容见“设置颜色”一节。

    设置画布的大小

    第一种方法:直接在subplots里用figsize=(x,y)指定:
    fig,axes = plt.subplots(figsize=(20,10))
    第二种方法:用plt.setp方式找到属性 figwidth, figheight

    fig.set_figwidth(20)
    fig.set_figheight(10)
    

    以上两种方法等效。

    设置颜色

    接查看自定义对象的属性(非常重要!)的例子:

    min_bar = df.wheat.idxmin()     #idxmin()是对一列求最小,返回其索引值 ,而非数据本身
    max_bar = df.wheat.idxmax()
    
    bar[min_bar].set_color('orange')
    bar[max_bar].set_color('red')
    

    设置图表标题和水平线

    axes.set(title = 'wheat each year', xlabel = 'year',ylabel='wheat')
    axes.axhline(df.wheat.mean(),c='red',ls='--')
    

    设置图表字体大小

    plt.rcParams.update({'axes.titlesize':45,'axes.labelsize':25})
    plt.rcParams.update({'font.size':20})
    

    绘图实例

    1.折线图 plot()详解

    绘制plot图-- 极简起步 plt.plot(x,y)

    import numpy as np 
    from matplotlib import pyplot as plt 
     
    x = np.arange(1,11) 
    y =  2  * x +  5 
    plt.title("Matplotlib demo") 
    plt.xlabel("x axis caption") 
    plt.ylabel("y axis caption") 
    plt.plot(x,y) 
    plt.show()
    

    绘制plot --讲解设定

    import numpy as np 
    from matplotlib import pyplot as plt 
    
    # 创建一个 8 * 6 点(point)的图,并设置分辨率为 80
    fig = plt.figure(figsize=(10,5),dpi=80) 
    # 创建一个新的 1 * 1 的子图,接下来的图样绘制在其中的第 1 块(也是唯一的一块)
    plt.subplot(1,1,1)
    
    X = np.linspace(-np.pi, np.pi, 256,endpoint=True)
    C,S = np.cos(X), np.sin(X)
    
    # 绘制余弦曲线,使用蓝色的、连续的、宽度为 1 (像素)的线条
    plt.plot(X, C, color="blue", linewidth=1.0, linestyle="-")
    # 绘制正弦曲线,使用绿色的、连续的、宽度为 1 (像素)的线条
    plt.plot(X, S, color="green", linewidth=1.0, linestyle="-")
    
    # 设置横轴的上下限
    plt.xlim(-4.0,4.0)
    # 设置横轴记号
    plt.xticks(np.linspace(-4,4,9,endpoint=True))
    # 设置纵轴的上下限
    plt.ylim(-1.0,1.0)
    # 设置纵轴记号
    plt.yticks(np.linspace(-1,1,5,endpoint=True))
    
    # 以分辨率 72 来保存图片
    # savefig("exercice_2.png",dpi=72)
    # 在屏幕上显示
    plt.show()
    

    绘制plot --进阶: 设定线型/颜色/粗细/标签

    import numpy as np 
    from matplotlib import pyplot as plt 
    
    fig = plt.figure(figsize=(10,5))
    data = np.linspace(0,10,100)      
    #在指定的间隔范围内返回均匀间隔的数字。在[start, stop]范围内计算,返回num个(默认为50)均匀间隔的样本。
    #参考:https://blog.csdn.net/benben_dog/article/details/85446452
    
    plt.plot(data, np.sin(data), c='r',ls='--',lw=4,label="label name")
    plt.xlabel('I am X Axis')
    plt.ylabel('I am Y Axis')
    plt.title("data desc")
    plt.legend()
    plt.show()
    

    绘制plot -- 另一个角度出发,设置风格并保存

    import matplotlib
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Data for plotting
    t = np.arange(0.0, 2.0, 0.01)
    s = 1 + np.sin(2 * np.pi * t)
    
    fig, ax = plt.subplots()
    ax.plot(t, s)
    
    ax.set(xlabel='time (s)', ylabel='voltage (mV)',
           title='About as simple as it gets, folks')
    ax.grid()
    
    fig.savefig("test.png")
    plt.show()
    

    绘制plot --双曲线图 plt.plot(x,y)

    import numpy as np 
    from matplotlib import pyplot as plt 
    
    fig = plt.figure(figsize=(10,5))
    data = np.linspace(0,10,100)
    plt.plot(data, np.sin(data), 'r-o', label="test legend A")
    plt.plot(data, np.cos(data), 'g--', label="test legend B")
    
    # 两个线也可以这样写: plt.plot(x_line1, y_line2, 'r', x_line2, y_line2, 'b')
    # 尝试取消下面注释运行(这种方式, 貌似图例不方便分开配置)
    # plt.plot(data, np.sin(data), 'r-o', data, np.cos(data), 'g--', label="A")
    
    plt.xlabel('I am X Axis')
    plt.ylabel('I am Y Axis')
    plt.title("data desc")
    plt.legend()
    plt.show()
    

    绘制多个plot --双图 plt.plot(x,y)

    import numpy as np 
    from matplotlib import pyplot as plt 
    x1 = np.linspace(0.0, 5.0)
    y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
    x2 = np.linspace(0.0, 2.0)
    y2 = np.cos(2 * np.pi * x2)
    
    plt.subplot(2, 1, 1)
    plt.plot(x1, y1, 'o-')
    plt.title('A tale of 2 subplots')
    plt.ylabel('Damped oscillation')
    
    plt.subplot(2, 1, 2)
    plt.plot(x2, y2, '.-')
    plt.xlabel('time (s)')
    plt.ylabel('Undamped')
    
    plt.show()
    

    绘制多个plot --双图(for循环写)

    import numpy as np
    import matplotlib.pyplot as plt
     
    plt.figure(1) # 创建图表1
    plt.figure(2) # 创建图表2
    ax1 = plt.subplot(211) # 在图表2中创建子图1
    ax2 = plt.subplot(212) # 在图表2中创建子图2
     
    x = np.linspace(0, 3, 100)
    for i in range(5):
        plt.figure(1)  # 选择图表1
        plt.plot(x, np.exp(i*x/3))
        plt.sca(ax1)   # 选择图表2的子图1
        plt.plot(x, np.sin(i*x))
        plt.sca(ax2)  # 选择图表2的子图2
        plt.plot(x, np.cos(i*x))
     
    plt.show()
    

    2 散点图/汽泡图 scatter()

    绘制scatter(x,y)入门

    import numpy as np 
    from matplotlib import pyplot as plt 
    x = np.linspace(0.05,10,1000)
    y = np.random.rand(1000)
    plt.scatter(x,y,label='scatter figure')
    plt.legend()
    plt.show()
    

    Matplotlib图表的导出

    plt.savefig()函数可以将Matplotlib图表导出不同的格式,包括pdf,png,jpg,svg等,注意:plt和word共同支持的格式有:jpg,jpeg,png,svg,tif,tiff
    其中,只有svg矢量图保存到word后不会模糊,其它格式的文件保存后模糊都十分严重。
    例:导出到pdf的代码如下:

    plt.savefig('filename.pdf',format='pdf')
    plt.show()  # plt.savefig()必须 在plt.show()之前调用
    

    如果要保持图片的清晰度,可以使用:

    plt.savefig('test.png',dpi=600)
    plt.show()
    

    Matplotlib中文支持问题

    Matplotlib 默认情况不支持中文,我们可以使用以下简单的方法来解决。
    1.从本机COPY一个字体到py文件的目录中
    并且在python语句中加入下一句:

    zhfont1 = matplotlib.font_manager.FontProperties(fname="Deng.ttf")  #这里引用的是'等线'中文字体
    

    然后就可以在title或lable中引用了。效果如下:

    import numpy as np 
    from matplotlib import pyplot as plt 
    import matplotlib
    
    # fname 为你指定的字体库路径
    zhfont1 = matplotlib.font_manager.FontProperties(fname="Deng.ttf") 
     
    x = np.arange(1,11) 
    y =  2  * x +  5 
    plt.title("菜鸟教程 - 测试", fontproperties=zhfont1) 
     
    # fontproperties 设置中文显示,fontsize 设置字体大小
    plt.xlabel("x 轴", fontproperties=zhfont1)
    plt.ylabel("y 轴", fontproperties=zhfont1)
    plt.plot(x,y) 
    plt.show()
    

    如果不知道把字体文件放在哪里,可以运行下一句命令,直接打开当前py文件所在的目录

    import os
    working_path = os.getcwd()
    os.system("explorer.exe %s" % working_path)    #打开py文件所在的目录
    

    2.不更新任何字体,直接使用命令:

    import numpy as np 
    from matplotlib import pyplot as plt 
    import matplotlib as mpl
    
    mpl.rcParams['font.sans-serif'] = ['KaiTi']
    mpl.rcParams['font.serif'] = ['KaiTi']
    mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题,或者转换负号为字符串
     
    x = np.arange(1,11) 
    y =  2  * x +  5 
    plt.title("菜鸟教程 - 测试") 
     
    plt.xlabel("x 轴")
    plt.ylabel("y 轴")
    plt.plot(x,y) 
    plt.show()
    

    其中,第三句mpl.rcParams['axes.unicode_minus'] = False是用来排除 ‘RuntimeWarning: Glyph 8722 missing from current font.’错误提示的
    上面那三句写成这样也是可以的:

    plt.rcParams['font.sans-serif'] = ['KaiTi']
    plt.rcParams['font.serif'] = ['KaiTi']
    plt.rcParams['axes.unicode_minus'] = False
    

    3.使用网上的思源黑体,思源黑体是 Adobe 与 Google 推出的一款开源字体。
    官网:https://source.typekit.com/source-han-serif/cn/
    GitHub 地址:https://github.com/adobe-fonts/source-han-sans/tree/release/OTF/SimplifiedChinese
    打开链接后,在里面选一个就好了:
    你也可以在网盘下载: https://pan.baidu.com/s/14cRhgYvvYotVIFkRVd71fQ 提取码: e15r。
    可以下载个 OTF 字体,比如 SourceHanSansSC-Bold.otf,将该文件文件放在当前执行的代码文件中

    Pandas DataFrame绘图

    对于普通的二维表,如果df只有2列,可以用下面的命令直接画折线图:

    df.plot()
    

    参考网站

    matplotlib中文网
    https://www.matplotlib.org.cn/

    《Python数据可视化之matplotlib实践》 作者:刘大成 中国工信出版社

  • 相关阅读:
    20175314 《Java程序设计》第六周学习总结
    20175314 结队编程项目——四则运算第一周
    20175314 《Java程序设计》迭代和JDB
    20175314 实验一 Java开发环境的熟悉
    20175314 《Java程序设计》第五周学习总结
    20175314 《Java程序设计》第四周学习总结
    20175314 《Java程序设计》第三周学习总结
    20175314 《Java程序设计》第二周学习总结
    20175314 《Java程序设计》第一周学习总结
    多态的成员特点
  • 原文地址:https://www.cnblogs.com/treasury-manager/p/14246955.html
Copyright © 2011-2022 走看看