python中动态生成的XLSXWriter图表-不引用

python中动态生成的XLSXWriter图表-不引用,python,excel,xlsxwriter,Python,Excel,Xlsxwriter,我正在使用我编写的下面的类尝试动态创建一个包含多个工作表的Excel文件,其中每个工作表中都有一个打印的数据框和一个柱状图 与代码(见下文)的交互应在您启动工作簿时起作用: test = Workbook('Test Workbook') test.produce() 然后,您可以添加任意数量的图表: test.add_chart(df, 'Df Title', 1) test.add_chart(df2, 'Df2 Title', 1) 然后生成工作簿: test = Workbook(

我正在使用我编写的下面的类尝试动态创建一个包含多个工作表的Excel文件,其中每个工作表中都有一个打印的数据框和一个柱状图

与代码(见下文)的交互应在您启动工作簿时起作用:

test = Workbook('Test Workbook')
test.produce()
然后,您可以添加任意数量的图表:

test.add_chart(df, 'Df Title', 1)
test.add_chart(df2, 'Df2 Title', 1)
然后生成工作簿:

test = Workbook('Test Workbook')
test.produce()
输入数据帧具有标题。第一列是文本类别,后面的列(数量不同)是小数形式的数据,以百分比的形式绘制

问题是:代码运行得相当好,似乎可以用图表单独生成所有工作表,但有些图表显示为“未引用”,这意味着当我单击柱状图中的条形图时,它不会突出显示源数据。使用代码生成的一些图表确实适当地引用了,所以我不确定问题在哪里,也没有明显的趋势

import xlsxwriter
import pandas as pd

class Workbook:

def __init__(self, workbook_name):
    self.workbook_name = workbook_name

    self.workbook = xlsxwriter.Workbook(str(self.workbook_name) + '.xlsx')

    self.letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']

def produce(self):
    self.workbook.close()
    print 'Created ' + str(self.workbook_name) + '.xlsx'

def print_frame(self, worksheet, dataframe, df_width, start_data_index):

    col_as_lists = []
    col_names = list(dataframe.columns.values)    

    # loops through columns in df and converts to list
    for n in range(0, df_width):
        col_n = dataframe[col_names[n]].tolist()

        # checks to see if column has numbers, if so -> convert to float!
        if n < start_data_index:
            col_n.insert(0, col_names[n])

        elif self.is_number(col_n[0]):
            convert = col_n[0:]
            convert = [float(x) for x in convert]
            convert.insert(0, col_names[n])
            col_n = convert
        else:
            col_n.insert(0, col_names[n])

        col_as_lists.append(col_n)

        # Prints each list into the worksheet.
        worksheet.write_column(self.letters[n] + '1', col_as_lists[n])

    #Formats numerical data as percentage
    percentformat = self.workbook.add_format({'num_format': '0%'})
    worksheet.set_column(self.letters[start_data_index] + ':' + self.letters[df_width], None, percentformat)


def add_chart(self, dataframe, tab_name, start_data_index):

    df_width = len(dataframe.columns)

    worksheet = self.workbook.add_worksheet(tab_name)
    self.print_frame(worksheet, dataframe, df_width, start_data_index)

    chart = self.workbook.add_chart({'type': 'column'})
    df_length = (len(dataframe.index))

    for n in range(start_data_index, df_width):

        chart.add_series({
            'name': '=' + tab_name +'!$' + self.letters[n] + '$1',
            'categories': '=' + tab_name +'!$' + self.letters[start_data_index - 1] + '$2:$'+ self.letters[start_data_index - 1] + '$' + str(df_length + 1),
            'values': '=' + tab_name +'!$' + self.letters[n] + '$2:$'+ self.letters[n] + '$' + str(df_length + 1),
            'fill': {'color': '#FFB11E'},
            'data_labels': {'value': True, 'center': True}
        })

    chart.set_title({'name': tab_name})
    chart.set_x_axis({'major_gridlines': {'visible': False}})
    chart.set_y_axis({'major_gridlines': {'visible': False}, 'max': .70})

    worksheet.insert_chart(self.letters[df_width + 2] + '2', chart)

    return

def is_number(self, s):
    """ Function used to help with detecting and converting floats 
    from string to number data types."""
    try:
        float(s)
        return True
    except ValueError:
        return False
导入xlsxwriter
作为pd进口熊猫
课堂练习册:
定义初始化(自我、工作簿名称):
self.workbook\u name=工作簿\u name
self.workbook=xlsxwriter.workbook(str(self.workbook_name)+'.xlsx')
self.letters=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P']
def生产(自):
self.workbook.close()
打印“已创建”+str(self.workbook_name)+“.xlsx”
def打印框(自身、工作表、数据框、df宽度、开始数据索引):
列为列表=[]
col_names=list(dataframe.columns.values)
#循环df中的列并转换为列表
对于范围内的n(0,df_宽度):
col_n=数据帧[col_name[n]]。tolist()
#检查列是否有数字,如果有->转换为浮点!
如果n<开始数据索引:
列n.插入(0,列名称[n])
elif self.is_编号(列[0]):
convert=列[0:]
convert=[convert中x的浮点(x)]
convert.insert(0,列名称[n])
col\u n=转换
其他:
列n.插入(0,列名称[n])
列为列表。追加(列)
#将每个列表打印到工作表中。
工作表.写入列(self.letters[n]+'1',列为列表[n])
#将数字数据格式化为百分比
percentformat=self.workbook.add_格式({'num_格式':'0%})
工作表.set_列(self.letters[start_data_index]+':'+self.letters[df_width],无,百分比格式)
def添加图表(自身、数据框、选项卡名称、开始数据索引):
df_width=len(dataframe.columns)
工作表=自我。工作簿。添加工作表(选项卡名称)
打印框架(工作表、数据框架、df宽度、开始数据索引)
chart=self.workbook.add_图表({'type':'column'})
df_长度=(len(dataframe.index))
对于范围内的n(起始数据索引、df宽度):
chart.add_系列({
'name':'='+tab_name+'!$'+self.letters[n]+'1',
“类别”:“=”+tab_name+”!$”+self.letters[start_data_index-1]+“$2:$”+self.letters[start_data_index-1]+“$”+str(df_length+1),
“值”:“=”+tab_name+”!$”+self.letters[n]+'$2:$”+self.letters[n]+'$'+str(df_长度+1),
'填充':{'color':'#FFB11E'},
'data_labels':{'value':True,'center':True}
})
图表.设置标题({'name':选项卡名称})
图表.设置x轴({'major_gridlines':{'visible':False})
图表.set_y_轴({'major_gridlines':{'visible':False},'max':.70})
工作表.插入图表(自记字母[df_宽度+2]+'2',图表)
返回
def是_编号(自身):
“”“用于帮助检测和转换浮动的函数
从字符串到数字数据类型。”“”
尝试:
浮球
返回真值
除值错误外:
返回错误

您的示例调用:

test.add_chart(df, 'Df Title', 1)
test.add_chart(df2, 'Df2 Title', 1)
建议您有时在名称中使用空格。当您尝试以下操作时,这会导致引用中断

'name': '=' + tab_name +'!$' + self.letters[n] + '$1',
这将评估为

'name': '=Df Title!$A$1',
(例如,当
tab\u name
等于
'Df Title'
n
等于
0
)时

您应该仍然能够使用带空格的图纸引用,但要用单引号括起来,如

'name': "='Df Title'!$A$1",
因此,一种更健壮的编码方式是

'name': "='" + tab_name +"'!$" + self.letters[n] + '$1',

我有点惊讶,这些图表竟然能与断页引用一起工作,但我自己并没有实际测试图表,只是测试了涉及工作表名称的普通单元格公式。

@John Y是正确的,您在图表范围引用中没有正确引用工作表名称

通过使用图表列表语法而不是字符串语法,可以避免此问题以及从数字到单元格引用的手动转换:

chart.add_series({
    'name':       ['Sheet1', 0, col],
    'categories': ['Sheet1', 1, 0,   max_row, 0],
    'values':     ['Sheet1', 1, col, max_row, col],
})
该片段来自


这也适用于代码中的其他一些地方。作为XlsxWriter的一般规则,您可以使用
行-列
语法(几乎)使用
A1
语法:。

看似“未引用”的图表:除了单击它们时不突出显示其源数据之外,这些图表是否正确?你的工作表名称中有空格吗?哇,是的,这似乎是个问题!当我从图纸名称中删除空格时,所有图表都显示正确!关于你的问题,是的,除了参考问题和数据标签显示为小数而不是百分比外,图表显示正确。