'Secondary axes issues for two scatterplots, openpyxl

I am trying to create charts with python and openpyxl. These charts have a three series each, two series plotted on the primary axis and the other series plotted on the secondary axis.

Here is my test data: https://docs.google.com/spreadsheets/d/12RlWx8g-7S8cwtG8swz9n5I2rwaMMh5q/edit?usp=sharing&ouid=104041081140482661384&rtpof=true&sd=true

Here is my code so far:

# openpyxl
from openpyxl import Workbook, load_workbook
from openpyxl.utils import get_column_letter
from openpyxl.utils.dataframe import dataframe_to_rows
from openpyxl.chart import *

# other
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# define input and output files
file_input = 'C:/LocalData/VirtualEnvironment_terraphase/Learning_TechwithTim_OpenPyXL/test_data1.xlsx'
file_output = 'C:/LocalData/VirtualEnvironment_terraphase/Learning_TechwithTim_OpenPyXL/result3.xlsx'

# create workbook
wb = Workbook()

# create main data frame
df_main = pd.read_excel(file_input)

# determine number of columns in dataframe, this will be used later
df_main_range_columns = len(df_main.columns) + 1

d={}

for index, LocCode in enumerate(df_main['LocCode'].unique()):
    d[LocCode] = df_main[df_main['LocCode'] == LocCode]
    
    df_local_range_rows = len(d[LocCode]) + 2
    
    # create charts
    chart_scatter_analytical = ScatterChart()
    chart_scatter_gwe = ScatterChart()
    chart_scatter_combined = ScatterChart()
    
    # create sheets
    wb.create_sheet(LocCode)
    ws = wb[LocCode]
    
    for dataframes in dataframe_to_rows(d[LocCode], index=True, header=True):
        ws.append(dataframes)
    
    for index, Analyte in enumerate(d[LocCode]['Analyte'].unique()):
        # get column indices
        for cell_value in ws.iter_cols(min_row=1, max_row=1, min_col=1, max_col=df_main_range_columns):
            for cell in cell_value:
                if cell.value == 'Date':
                    col_date = cell.column
                elif cell.value == 'Concentration':
                    col_conc = cell.column
                elif cell.value == 'Analyte':
                    col_analyte = cell.column
                    
        # get row indices for analyte
        row_analyte_list = []
        
        for cell_value in ws.iter_rows(min_row=3, max_row=df_local_range_rows, min_col=col_analyte, max_col=col_analyte):            
            for cell in cell_value:
                if cell.value == Analyte:
                    row_analyte_list.append(cell.row)
        
        row_min = min(row_analyte_list)
        row_max = max(row_analyte_list)      
                        
        data_x = Reference(ws, 
                           min_col=col_date, 
                           max_col=col_date, 
                           min_row=row_min, 
                           max_row=row_max)
        
        data_y = Reference(ws, 
                           min_col=col_conc, 
                           max_col=col_conc,
                           min_row=row_min, 
                           max_row=row_max)

        # create series
        series_analyte = Series(values = data_y, xvalues=data_x, title=Analyte)
        
        # add series to charts
        # add analytical results to one chart, GWE to another
        if Analyte == 'GWE':
            chart_scatter_gwe.series.append(series_analyte)
        else:
            chart_scatter_analytical.series.append(series_analyte)
            
    chart_scatter_analytical.y_axis.crosses = 'autoZero'
    
    # set y-axis on gwe chart to secondary position
    chart_scatter_gwe.y_axis.crosses = 'max'
    
    # combine charts
    chart_scatter_gwe += chart_scatter_analytical
    chart_scatter_combined += chart_scatter_analytical    
    chart_scatter_combined += chart_scatter_gwe
        
    ws.add_chart(chart_scatter_analytical, "H1")
    ws.add_chart(chart_scatter_gwe, "H18")
    ws.add_chart(chart_scatter_combined, "R1")
   
wb.save(file_output)

This is the result I'm getting:

enter image description here

So, I'm interested in the chart_scatter_gwe but you can see that everything is plotted on the secondary axis. Seems like the chart_scatter_analytical.y_axis.crosses = 'autoZero' is not being recognized?

One thing I tried was switching the chart type of chart_scatter_gwe to a line chart. This actually got two separate axes on the chart, so maybe this method for two scatter charts needs to be different?

Any ideas/guidance would be greatly appreciated. Thanks,



Solution 1:[1]

Ok so I was able to get this working by adding the line chart_scatter_analytical.y_axis.axId = 200 above chart_scatter_gwe.y_axis.crosses = "max"

Not 100% sure why this worked, I saw the examples in the documentation had this line so I thought I'd try it. I'll keep looking through the docs/source code to understand the axId better.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Marcus