Диаграмма с вторичной осью Y и осью X в качестве даты - PullRequest
0 голосов
/ 08 ноября 2018

Я пытаюсь создать диаграмму в openpyxl со вторичной осью Y и DateAxis для значений x.

Для этого MWE я адаптировал пример вторичной оси с примером DateAxis .

from datetime import datetime
from openpyxl import Workbook, chart

# set to True to fail/create an invalid document
# set to False to generate a valid, but ugly/useless chart
DATES_ON_2ND = True

wb = Workbook()
ws = wb.active

xvals = ['date', *[datetime(2018, 11, d, d+12) for d in range(1, 7)]]
avals = ['aliens', 6, 3, 4, 3, 6, 7]
hvals = ['humans', 10, 40, 50, 20, 10, 50]

for row in zip(xvals, avals, hvals):
    ws.append(row)

dates = chart.Reference(ws, min_row=2, max_row=7, min_col=1, max_col=1)
aliens = chart.Reference(ws, min_row=1, max_row=7, min_col=2, max_col=2)
humans = chart.Reference(ws, min_row=1, max_row=7, min_col=3, max_col=3)

c1 = chart.LineChart()
c1.x_axis = chart.axis.DateAxis(crossAx=100)
c1.x_axis.title = "Date"
c1.x_axis.crosses = "min"
c1.x_axis.majorTickMark = "out"
c1.x_axis.number_format = "yyyy-mmm-dd"

c1.add_data(aliens, titles_from_data=True)
c1.set_categories(dates)
c1.y_axis.title = 'Aliens'

# Create a second chart
c2 = chart.LineChart()
if DATES_ON_2ND:
    c2.x_axis = chart.axis.DateAxis(crossAx=100)
    c2.x_axis.number_format = "yyyy-mmm-dd"

c2.x_axis.crosses = "min"
c2.add_data(humans, titles_from_data=True)
c2.set_categories(dates)

# c2.y_axis.axId = 200
c2.y_axis.title = "Humans"

# Display y-axis of the second chart on the right
# by setting it to cross the x-axis at its maximum
c1.y_axis.crosses = "max"
c1 += c2

ws.add_chart(c1, "E4")
wb.save("secondary.xlsx")

Когда я оставляю вторичную ось x в качестве категориальной оси, создается действительный документ Excel, даже если диаграмма не та, которую я хочу. Но установка вспомогательной оси как DateAxis так же, как и первичная ось, создает недопустимый поврежденный файл, который не отображает какую-либо диаграмму.

Есть ли уловка с этим, которую я пропускаю?

1 Ответ

0 голосов
/ 08 ноября 2018

Итак, как отмечалось в моих комментариях, в DateAxes нет особого преимущества, но если вы используете их, то у них будет идентификатор по умолчанию 500. Это важно, потому что это значение, которое нужно осям Y пересечь. CrossAx для оси категории / даты не имеет значения. У меня работает следующее:

from datetime import datetime
from openpyxl import Workbook, chart

wb = Workbook()
ws = wb.active

xvals = ['date', *[datetime(2018, 11, d, d+12) for d in range(1, 7)]]
avals = ['aliens', 6, 3, 4, 3, 6, 7]
hvals = ['humans', 10, 40, 50, 20, 10, 50]

for row in zip(xvals, avals, hvals):
    ws.append(row)

dates = chart.Reference(ws, min_row=2, max_row=7, min_col=1, max_col=1)
aliens = chart.Reference(ws, min_row=1, max_row=7, min_col=2, max_col=2)
humans = chart.Reference(ws, min_row=1, max_row=7, min_col=3, max_col=3)

c1 = chart.LineChart()
c1.x_axis = chart.axis.DateAxis() # axId defaults to 500
c1.x_axis.title = "Date"
c1.x_axis.crosses = "min"
c1.x_axis.majorTickMark = "out"
c1.x_axis.number_format = "yyyy-mmm-dd"

c1.add_data(aliens, titles_from_data=True)
c1.set_categories(dates)
c1.y_axis.title = 'Aliens'
c1.y_axis.crossAx = 500
c1.y_axis.majorGridlines = None

# Create a second chart
c2 = chart.LineChart()
c2.x_axis.axId = 500 # same as c1

c2.x_axis.crosses = "min"
c2.add_data(humans, titles_from_data=True)
c2.set_categories(dates)

c2.y_axis.axId = 20
c2.y_axis.title = "Humans"
c2.y_axis.crossAx = 500

# Display y-axis of the second chart on the right
# by setting it to cross the x-axis at its maximum
c1.y_axis.crosses = "max"
c1 += c2

ws.add_chart(c1, "E4")
wb.save("secondary.xlsx")
...