具有两个不同参考的 Openpyxl 条形图

问题描述 投票:0回答:1

我在 openpyxl v3.1.1 中构建复杂的条形图时遇到问题。所有指南都有简单的示例:

chart1 = BarChart()
data = Reference(ws, min_col=2, min_row=1, max_row=7, max_col=3)  # Y data
cats = Reference(ws, min_col=1, min_row=2, max_row=7) # X data
chart1.add_data(data, titles_from_data=True)
# or series_2 = Series(data_dec, title=f"Title") when Title not the first row
# chart1.append(series_2)
chart1.set_categories(cats)
ws.add_chart(chart1, "A10")  # draw chart

但是参考只包含一组“行”,但我需要不止一个。在 MS Excel 中,我可以通过按 Ctrl 并选择另一个“行”块来完成此操作。

是否可以在 openpyxl 中做同样的事情?

说明我的问题的小例子我得到了表格

数据-1 数据-2
2010 年 1 月 1 日 0.1
2010 年 1 月 2 日 0.2
2010 年 1 月 1 日 0.3
2010 年 2 月 1 日 0.4
2010 年 2 月 2 日 0.5
2010 年 2 月 3 日 0.6
2011 年 1 月 1 日 0.7
2011 年 1 月 2 日 0.8
2011 年 1 月 3 日 0.9

我需要在 MS Excel 中构建一个一月份的图表(2010-Jan-1、2010-Jan-2、2010-Jan-3、2011-Jan-1、2011-Jan-2、2011-Jan-3)我可以使用 Ctrl 按钮选择单元格并得到如下公式: =test_1!$A$2:$A$4;test_1!$A$8:$A$10

但是在 openpyxl 中找不到任何东西来联合两个引用。

python excel openpyxl
1个回答
0
投票

使用 XLSXWriter 和 XlWings 创建图表的示例。

XLSXWRITER
使用 xlsxwriter,您只需输入非连续范围作为

=test_1!$A$2:$A$4;test_1!$A$8:$A$10
,尽管这确实会触发警告消息,因为 xlsxwriter 无法从该范围正确提取工作表名称。它表示工作簿的工作表列表中不存在工作表名称(提取的),但似乎不会影响工作簿和图表的创建。

sheet_name = 'test_1'
workbook = xlsxwriter.Workbook("xlsxwriter_chart.xlsx")
worksheet = workbook.add_worksheet(sheet_name)

### Formatting for data
bold = workbook.add_format({"bold": 1})
# date_format = workbook.add_format({"num_format": "d/mm/yyyy"})
date_format = workbook.add_format({"num_format": "yyyy-mmm-d"})
value_format = workbook.add_format({"num_format": "0.0"})

# Worksheet data that the charts will use
headings = ['Data-1', 'Data-2']
data_list = [
    [40179, 0.1],
    [40180, 0.2],
    [40181, 0.3],
    [40210, 0.4],
    [40211, 0.5],
    [40212, 0.6],
    [40544, 0.7],
    [40545, 0.8],
    [40546, 0.9],
]

### Add data to Sheet with some formatting
worksheet.write_row("A1", headings, bold)
for row, data in enumerate(data_list, 2):
    worksheet.write(f"A{row}", data[0], date_format)
    worksheet.write(f"B{row}", data[1], value_format)

### Create the Bar chart.
chart = workbook.add_chart({"type": "bar"})

### Adjust chart objects to display values better
chart.set_x_axis({
    'major_gridlines': {
        'visible': False,
    },
})
chart.set_y_axis({
    "date_axis": True,
    "min": date(2009, 12, 1),
    "max": date(2011, 2, 1),
})

# Configure the series ranges.
chart.add_series(
    {
        "categories": f"={sheet_name}!$A$2:$A$4,{sheet_name}!$A$8:$A$10",
        "values": f"={sheet_name}!$B$2:$B$4,{sheet_name}!$B$8:$B$10",
        "gridline": False
    }
)

# Insert the chart into the worksheet (with an offset).
worksheet.insert_chart("D2", chart, {"x_offset": 25, "y_offset": 10})

### Widen column A for date values
worksheet.set_column('A:A', 10)
workbook.close(

XL翼
同样,您可以使用“set_source_data”或“FullSeriesCollection”输入非连续范围,尽管 FullSeriesCollection 需要范围中包含工作表名称。

import xlwings as xw
from xlwings import constants

with xw.App(visible=False) as app:
    wb = xw.Book()
    ws = wb.sheets[0]

    # Add the worksheet data to be plotted.
    data = [10, 40, 50, 20, 10, 50]
    data_list = [
        ['Data-1', 'Data-2'],
        [40179, 0.1],
        [40180, 0.2],
        [40181, 0.3],
        [40210, 0.4],
        [40211, 0.5],
        [40212, 0.6],
        [40544, 0.7],
        [40545, 0.8],
        [40546, 0.9],
    ]
    ### Format the cells with data
    ws.range('A1').value = data_list
    ws.range('A1:B1').font.bold = True
    ws.range('A2:A10').number_format = "yyyy-mmm-d"

    ### Create new chart object Chart.
    chart = ws.charts.add(left=200, top=10, width=520, height=380)

    ### Add Chart and set type
    chart.api[1].SeriesCollection().NewSeries()
    chart.api[1].FullSeriesCollection(1).ChartType = constants.ChartType.xlBarClustered

    ### Select non-contiguous range for X axis
    chart.set_source_data(ws.range('B2:B4, B8:B10'))
    ### Select non-contiguous range for Y axis
    chart.api[1].FullSeriesCollection(1).XValues = f"={ws.name}!A2:A4,{ws.name}!A8:A10"

    ### Set date range scale
    chart.api[1].Axes(constants.AxisType.xlCategory).MinimumScale = 40148
    chart.api[1].Axes(constants.AxisType.xlCategory).MaximumScale = 40575
    chart.api[1].Axes(2).MajorGridlines.Delete()

    wb.save('xlwings_chart.xlsx')
    wb.close()

如前所述,尽管值在顶部和底部倾斜,但该图表可能不是很有用

© www.soinside.com 2019 - 2024. All rights reserved.