"""
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)
openpyxl_chart_demos(openpyxl三:图表相关操作:创建图表、使用轴、图表布局)
最新推荐文章于 2025-03-20 20:33:13 发布