openpyxl_chart_demos(openpyxl三:图表相关操作:创建图表、使用轴、图表布局)

"""
openpyxl_chart_demos.py

(openpyxl三:图表相关操作:创建图表、使用轴、图表布局)

使用:
创建图表:
openpyxl.chart.Reference(), Chart.add_data(), Worksheet.add_chart();

使用轴:
Chart.title / style / x_axis.title / y_axis.title, 
Chart.x_axis.scaling.min, 
Chart.x_axis.Scaling.max, 

openpyxl.chart.Series(), Chart.series.appedn(Series), Chart.append(Series),
Chart.x_axis.scaling.logBase

Chart.x_axis.scaling.orientation

Chart.y_axis.crosses, Chart.y_axis.majorGridlines
Chart1 + Chart2

图表布局:
openpyxl.chart.layout.Layout(): 为手动布局对象ManualLayout(),
openpyxl.chart.layout.ManualLayout():为Lyaout()类的参数,
Chart.layout,
Chart.legend.position;


"""


import openpyxl
from openpyxl import Workbook, load_workbook
from openpyxl.chart import (AreaChart,           #AreaChart面积图表(2D区域图)
                            AreaChart3D,         #AreaChart面积图表(3D区域图)
                            
                            BarChart,            #BarChart条形图/柱形图/成交量图
                            
                            BubbleChart,         #BubbleChart气泡图
                            LineChart,           #LineChart折线图
                            LineChart3D,         #LineChart3D折线图
                            ScatterChart,        #ScatterChart散点图
                            PieChart,            #PieChart饼图
                            PieChart3D,          #PieChart3D饼图3D
                            ProjectedPieChart,   #ProjectedPieChart投影饼图
                            
                            StockChart,          #StockChart股票图
                            
                            Reference,           #用来对单元范围进行标准化引用
                            Series)              #用来方便创建图表数据系列
from copy import deepcopy                        #深层复制
from openpyxl.chart.axis import DateAxis         #时间轴
from openpyxl.chart.series import DataPoint      #
from openpyxl.chart.layout import (Layout,       #布局
                                   ManualLayout  #手动布局
                                   )




wb = Workbook()
wb_filename = r'openpyxl_cases\openpyxl_chart_demos_case1.xlsx'


####################  图表类型
#参考文件 openpyxl_chart_type_demos.py


####################  创建图表
#图表至少由一系列一个或多个数据点组成。系列本身由对单元格范围的引用组成。

#####
#使用:openpyxl.chart.Reference(worksheet=None, min_col=None, min_row=None, max_col=None, max_row=None, range_string=None)
#来对单元范围进行标准化引用。

#使用:Chart.add_data() 来给图表添加系列数据。
#使用:Worksheet.add_chart() 来给工作表添加图表 至 指定cell位置。

#注意:使用Worksheet.append()方法添加的内容必须为 序列类型。
ws_cjtb = wb.create_sheet('创建图表', index=0)
for i in range(10):
    ws_cjtb.append([i])         

chart = BarChart()
values = Reference(ws_cjtb, min_col=1, min_row=1, max_col=1, max_row=10)
chart.add_data(values)
ws_cjtb.add_chart(chart)        #如果不指定参数2锚定单元格,则默认在'E15'位置插入图表。


####################  使用轴


##### 设置轴线的 最小值 和 最大值

#####
#使用:Chart.title  属性 来赋值添加 图表标题
#使用:Chart.style  属性 来赋值设置 图表样式
#使用:Chart.x_axis.title 属性 来赋值添加 X轴标题
#使用:Chart.y_axis.title 属性 来赋值添加 y轴标题

#使用:Chart.x_axis.scaling.min  属性 来赋值X轴的最小值
#使用:Chart.x_axis.scaling.max  属性 来赋值X轴的最大值
#使用:Chart.y_axis.scaling.min  属性 来赋值Y轴的最小值
#使用:Chart.y_axis.scaling.max  属性 来赋值Y轴的最大值

ws_zxzxdz = wb.create_sheet('轴线最小大值', index=0)
ws_zxzxdz.append(['X', '1/X'])
for x in range(-10, 11):
    if x:
        ws_zxzxdz.append([x, 1.0 / x])

chart1 = ScatterChart()
chart1.title = "Full Axes"
chart1.x_axis.title = 'x'
chart1.y_axis.title = '1/x'
chart1.legend = None

chart2 = ScatterChart()
chart2.title = "Clipped Axes"
chart2.x_axis.title = 'x'
chart2.y_axis.title = '1/x'
chart2.legend = None

chart2.x_axis.scaling.min = 0        #设置X轴的最小值
chart2.y_axis.scaling.min = 0        #设置Y轴的最小值
chart2.x_axis.scaling.max = 11       #设置X轴的最大值
chart2.y_axis.scaling.max = 1.5      #设置Y轴的最大值

#####
#使用:openpyxl.chart.Series(values, xvalues=None, zvalues=None, title=None, title_from_data=False)
#来方便创建图表数据系列
#参数values       : 指定 y轴值
#参数xvalues=None : 指定 x轴值
#参数zvalues=None : 指定 大小
#参数title=None   : 指定图表的系列标题 

#使用:Chart.series.append(Series) 方法来添加 经过Series类 方便创建的气泡图表数据系列。
#等同于 Chart.append(Series)
#使用:Chart.series 属性 来获取所有数据系列值。

x = Reference(ws_zxzxdz, min_col=1, min_row=2, max_row=22)
y = Reference(ws_zxzxdz, min_col=2, min_row=2, max_row=22)
s = Series(y, xvalues=x)
chart1.series.append(s)
chart2.series.append(s)

ws_zxzxdz.add_chart(chart1, "C1")
ws_zxzxdz.add_chart(chart2, "C20")


##### 设置轴线 按倍数显示
#####
#使用:内置函数enumerate(序列) 来将参数序列组合成一个 索引序列。

#使用:Chart.x_axis.scaling.logBase  属性 来进行X轴的数字倍数显示
#使用:Chart.y_axis.scaling.logBase  属性 来进行Y轴的数字倍数显示
#注意:如果对X轴按数字倍数比例显示,则X轴域中的负值将被丢弃。

import math
ws_zxbsxs = wb.create_sheet('轴线倍数显示', index=0)
ws_zxbsxs.append(['X', 'Gaussian'])
for i, x in enumerate(range(-10, 11)):  #使用:内置函数enumerate(序列) 来将参数序列组合成一个 索引序列。
    ws_zxbsxs.append([x, '=EXP(-(($A${row}/6)^2))'.format(row= i+2)])
    
chart1 = ScatterChart()
chart1.title = 'No Scaling'
chart1.x_axis.title = 'X'
chart1.y_axis.title = 'Y'
chart1.legend = None

chart2 = ScatterChart()
chart2.title = 'X Log Scale'
chart2.x_axis.title = 'X (log10)'
chart2.y_axis.title = 'Y'
chart2.legend = None
chart2.x_axis.scaling.logBase = 2    #设置 X轴线 按数字倍数显示

chart3 = ScatterChart()
chart3.title = 'Y Log Scale'
chart3.x_axis.title = 'X'
chart3.y_axis.title = 'Y (log10)'
chart3.legend = None
chart3.y_axis.scaling.logBase = 10   #设置 X轴线 按数字倍数显示

chart4 = ScatterChart()
chart4.title = 'Both Log Scale'
chart4.x_axis.title = 'X (log10)'
chart4.y_axis.title = 'Y (log10)'
chart4.legend = None
chart4.x_axis.scaling.logBase = 10   #设置 X轴线 按数字倍数显示
chart4.y_axis.scaling.logBase = 10   #设置 X轴线 按数字倍数显示

chart5 = ScatterChart()
chart5.title = 'Log Scale Base e'
chart5.x_axis.title = 'X (ln)'
chart5.y_axis.title = 'Y (ln)'
chart5.legend = None
chart5.x_axis.scaling.logBase = math.e    #math.e 表示一个常量。
chart5.y_axis.scaling.logBase = math.e    #设置 X轴线 按 math.e常量 的倍数显示

x = Reference(ws_zxbsxs, min_col=1, min_row=2, max_row=22)
y = Reference(ws_zxbsxs, min_col=2, min_row=2, max_row=22)
s = Series(y, xvalues=x)
chart1.append(s)
chart2.append(s)
chart3.append(s)
chart4.append(s)
chart5.append(s)

ws_zxbsxs.add_chart(chart1,'C1')
ws_zxbsxs.add_chart(chart2,'K1')
ws_zxbsxs.add_chart(chart3,'C18')
ws_zxbsxs.add_chart(chart4,'K18')
ws_zxbsxs.add_chart(chart5,'F35')


##### 设置轴线的方向
#轴可以“正常”显示或反向显示。
#轴方向由比例orientation属性控制,该属性的值可以 'minMax'为法向或'maxMin'反向。

#####
#使用:Chart.x_axis.scaling.orientation 属性 来指定轴方向从小到大minMax / 从大到小maxMin

ws_zxfx = wb.create_sheet('轴线方向', 0)
ws_zxfx['A1'] = 'Archimedean Spiral'
ws_zxfx.append(['T', 'X', 'Y'])
for i, t in enumerate(range(100)):
    ws_zxfx.append([t/16.0, '=$A${row}*COS($A${row})'.format(row= i+3),
                            '=$A${row}*SIN($A${row})'.format(row= i+3)])

chart1 = ScatterChart()
chart1.title = 'Default Orientation'
chart1.x_axis.title = 'X'
chart1.y_axis.title = 'Y'
chart1.legend = None

chart2 = ScatterChart()
chart2.title = 'Flip X'
chart2.x_axis.title = 'X'
chart2.y_axis.title = 'Y'
chart2.legend = None
chart2.x_axis.scaling.orientation = 'maxMin'    #设置X轴线防线 从大到小
chart2.y_axis.scaling.orientation = 'minMax'    #设置Y轴线方向 从小到大

chart3 = ScatterChart()
chart3.title = 'Flip Y'
chart3.x_axis.title = 'X'
chart3.y_axis.title = 'Y'
chart3.legend = None
chart3.x_axis.scaling.orientation = 'minMax'    #设置轴线方向 从小到大
chart3.y_axis.scaling.orientation = 'maxMin'    #设置轴线方向 从大到小

chart4 = ScatterChart()
chart4.title = 'Flip Both'
chart4.x_axis.title = 'X'
chart4.y_axis.title = 'Y'
chart4.legend = None
chart4.x_axis.scaling.orientation = 'maxMin'    #设置轴线方向 从大到小
chart4.y_axis.scaling.orientation = 'maxMin'    #设置轴线防线 从大到小

x = Reference(ws_zxfx, min_col=2, min_row=2, max_row=102)
y = Reference(ws_zxfx, min_col=3, min_row=2, max_row=102)
s = Series(y, xvalues=x)
chart1.append(s)
chart2.append(s)
chart3.append(s)
chart4.append(s)

ws_zxfx.add_chart(chart1, 'D1')
ws_zxfx.add_chart(chart2, 'L1')
ws_zxfx.add_chart(chart3, 'D18')
ws_zxfx.add_chart(chart4, 'L18')


##### 添加轴线
#添加第二个轴,实际上就是 创建一个只有Y轴,且与第一个图标共享X轴的第二个图表。

#####
#使用:Chart.y_axis.crosses = 'max' 属性 来设置在右侧显示图表的Y轴,将其设置为最大横过X轴。
#使用:Chart.y_axis.majorGridlines = None 来设置网格线。
#使用:Chart1 + Chart2  方式 来添加第二个轴线,如:柱状图 + 折线图。

ws_tjzx = wb.create_sheet('添加轴线', 0)
rows = [
        ['Aliens', 2, 3, 4, 5, 6, 7],
        ['Humans', 10, 40, 50, 20, 10, 50]
       ]
for row in rows:
    ws_tjzx.append(row)

c1 = BarChart()      #第一个图表,柱状线。
c1.title = 'Survey results'
c1.x_axis.title = '1 Days'
c1.y_axis.title = '1 Aliens'
c1.y_axis.majorGridlines = None                           #设置Y轴网格线 
v1 = Reference(ws_tjzx, min_col=1, max_col=7, min_row=1)  #引用第一行的所有数据
c1.add_data(v1, titles_from_data=True, from_rows=True)

c2 = LineChart()     #第二个图标,折线图表。
c2.y_axis.title = '2 Humans'
c2.y_axis.axId = 200
v2 = Reference(ws_tjzx, min_col=1, max_col=7, min_row=2)  #引用第二行的所有数据
c2.add_data(v2, titles_from_data=True, from_rows=True)

c1.y_axis.crosses = 'max'  #在右侧显示图表的y轴,将其设置为最大横过x轴
c1 += c2                   #使用:Chart1 + Chart2  方式 来添加第二个轴线,如:柱状图 + 折线图。



ws_tjzx.add_chart(c1, 'D4')



####################  图表布局


##### 图表布局 和 图例布局

#使用:openpyxl.chart.layout.Layout(self, manualLayout=None, extLst=None) 类
#来创建布局对象。
#参数manualLayout: 为手动布局对象ManualLayout()

#使用:openpyxl.chart.layout.ManualLayout(self, layoutTarget=None, 
#xMode=None, yMode=None, wMode='factor', hMode='factor', 
#x=None, y=None, w=None, h=None, extLst=None) 类 
#来创建 手动布局对象。
#参数x,y: 指定位置
#参数h,w: 指定大小

#使用:Chart.layout 属性 来赋值 设置布局为 创建的手动布局对象。
#使用:Chart.legend.position 属性 来设置图例的位置:r,l,t,b,tr,分别代表:右、左、顶、底、右上。


ws_tbbj = wb.create_sheet('图表布局', 0)
rows = [
        ['Size', 'Batch 1', 'Batch 2'],
        [2, 40, 30],
        [3, 40, 25],
        [4, 50, 30],
        [5, 30, 25],
        [6, 25, 35],
        [7, 20, 40]
       ]
for row in rows:
    ws_tbbj.append(row)

ch1 = ScatterChart()
xvalues = Reference(ws_tbbj, min_col=1, min_row=2, max_row=7)
for i in range(2,4):
    values = Reference(ws_tbbj, min_col=i, min_row=1, max_row=7)
    series = Series(values, xvalues, title_from_data=True)
    ch1.series.append(series)

#散点图表1
ch1.title = 'Default layout'
ch1.style = 13
ch1.x_axis.title = 'Size'
ch1.y_axis.title = 'Percentage'
ch1.legend.position = 'r'          #设置图例的位置:r,l,t,b,tr,分别代表:右、左、顶、底、右上。
ws_tbbj.add_chart(ch1, 'B10')


#散点图表2
ch2 = deepcopy(ch1)
ch2.title = 'Manual chart layout'
ch2.legend.position = 'tr'        #设置图例的位置:右上
ch2.layout = Layout(manualLayout = ManualLayout(x=0.25, y=0.25,    #x,y调整位置
                                                h=0.5, w=0.5       #h,w调整大小
                                                ))   
ws_tbbj.add_chart(ch2, 'K10')


#散点图表3
ch3 = deepcopy(ch1)
ch3.title = 'Manual chart layou, edge mode'
ch3.layout = Layout(ManualLayout(x=0.25, y=0.25,    #x,y调整位置
                                 h=0.5, w=0.5,      #h,w调整大小
                                 xMode='edge', 
                                 yMode='edge'
                                 ))
ws_tbbj.add_chart(ch3, 'B27')


#单点图表4
ch4 = deepcopy(ch1)
ch4.title = 'Manual legend layout'
ch4.legend.layout = Layout(manualLayout = ManualLayout(x=0, y=0.9,     #x,y调整位置
                                                       h=0.1, w=0.5,   #h,w调整大小
                                                       xMode='edge',   
                                                       yMode='edge'
                                                       ))
ws_tbbj.add_chart(ch4, 'K27')





wb.save(wb_filename)









你可能感兴趣的:(爬虫相关)