XlsxWriter : make a solid filled data bar - python

I have successfully created some data bar plot with the python module xlsxwriter by its conditional_format method.
However, is it possible to specify the fill pattern of condition format within xlswriter or python generally?
I tried the following code which didn't work:
myformat = workbook.add_format()
myformat .set_pattern(1)
worksheet.conditional_format(0, 4, 0, 4, {'type': 'data_bar',
'min_value': 0,
'min_type': 'num',
'max_value': 110,
'max_type': 'num',
'bar_color': '#C00000',
'format': myformat})

It is possible to set the pattern of the format for some conditional formats with XlsxWriter.
However, as far as I know, it isn't possible, in Excel, to set a patten type for data_bar conditional formats.
You could do it with a cell format:
import xlsxwriter
workbook = xlsxwriter.Workbook('hello_world3.xlsx')
worksheet = workbook.add_worksheet()
myformat = workbook.add_format()
myformat.set_pattern(1)
myformat.set_bg_color('#C00000')
worksheet.conditional_format(0, 4, 0, 4, {'type': 'cell',
'criteria': 'between',
'minimum': 0,
'maximum': 110,
'format': myformat})
worksheet.write(0, 4, 50)
workbook.close()
If, on the other hand, you are looking for a non-gradient data_bar fill, that isn't currently supported.

for newer version, you only need the 'data_bar_2010' property to true:
worksheet.conditional_format(0, 4, 0, 4, {'type': 'data_bar','data_bar_2010': True})
see the xlsxwriter documents here

Related

How to convert SQLAlchemy data into JSON format?

I am working on SQLAlchemy and want to fetch the data from database and convert the same into JSON format.
I have below code :
db_string = "postgres://user:pwd#10.**.**.***:####/demo_db"
Base = declarative_base()
db = create_engine(db_string)
record = db.execute("SELECT name, columndata, gridname, ownerid, issystem, ispublic, isactive FROM col.layout WHERE (ispublic=1 AND isactive=1) OR (isactive=1 AND ispublic=1 AND ownerid=ownerid);")
for row in record:
result.append(row)
print(result)
Data is coming in this format:
[('layout-1', {'theme': 'blue', 'sorting': 'price_down', 'filtering': ['Sub Strategye', 'PM Strategy']}, 'RealTimeGrid', 1, 0, 1, 1), ('layout-2', {'theme': 'orange', 'sorting': 'price_up', 'filtering': ['FX Rate', 'Start Price']}, 'RealBalancing Grid', 2, 0, 1, 1), ('layout-3', {'theme': 'red', 'sorting': 'mv_price', 'filtering': ['Sub Strategye', 'PM Strategy']}, 'RT', 3, 0, 1, 1)]
But I am facing a lot of issues to convert the above result into JSON Format. Please suggest.
Your data is basically a list of tuples.
like first tuple is like
('layout-3',
{'filtering': ['Sub Strategye', 'PM Strategy'],
'sorting': 'mv_price',
'theme': 'red'},
'RT',
3,
0,
1,
1)
if you want to convert whole data as it is to json, you can use json module dumps function
import json
jsn_data = json.dumps(data)
Your list of tuple is converted to json
[["layout-1", {"theme": "blue", "sorting": "price_down", "filtering": ["Sub Strategye", "PM Strategy"]}, "RealTimeGrid", 1, 0, 1, 1], ["layout-2", {"theme": "orange", "sorting": "price_up", "filtering": ["FX Rate", "Start Price"]}, "RealBalancing Grid", 2, 0, 1, 1], ["layout-3", {"theme": "red", "sorting": "mv_price", "filtering": ["Sub Strategye", "PM Strategy"]}, "RT", 3, 0, 1, 1]]
but If you need json formate as key value pair , first need to convert the result in python dictionary then use json.dumps(dictionary_Var)
What you want to accomplish is called "serialization".
You can follow Sudhanshu Patel's answer if you just want to dump json into response.
However if you intend to produce a more sophisticated application, consider using a serialization library. You'll be able to input data from request into db, check if input data is in the right format, and send response in a standarised format.
Check these libraries:
Marshmallow
Python's own Pickle

Python Pandas: export to excel format a row 'Bold' without condition

I have what I feel could be a silly question but it seems I can't find the answer:
How to, while exporting to Excel, set a row/range to bold?
I know how to conditional format e.g.
format1 = workbook.add_format({'bg_color': '#FFC7CE',
'font_color': '#9C0006'})
...
worksheet.conditional_format('C2:AF41', {'type': 'cell', 'criteria': '<', 'value': 0, 'format': format1})
or even to format columns:
border_format = workbook.add_format({
'border': 1,
'align': 'center',
'font_size': 10
})
...
worksheet.set_column(0, 0, 30, border_format)
But let's say I want for row A1:A40 to be written in bold, whitout any particular criteria? I just want to set to bold or a color or any formatting a given range whatever data it may contain.
In this case, for instance, apply 'format1' to range A1:A40 whatever the values.
Does anyone know the answer?
It looks like there isn't a helper function specifically designed for this, according to github.
But Gabriel's answer to a similar question proposes a workaround, where you use two (or more) conditional formats to cover all values:
worksheet.conditional_format('A1:A40', {'type': 'cell',
'criteria': '>=', 'value': 0, 'format': format1})
worksheet.conditional_format('A1:A40', {'type': 'cell',
'criteria': '<', 'value': 0, 'format': format1})

xlsxwriter conditional formatting icon_set with mid value= 0 not showing proper arrow

The issue :
I want to apply conditional formatting icon_set using xlsx to a column but do not get the right arrows for the right values
This is my desired output :
This is my current output:
This is my code:
writer.sheets[sheet].conditional_format('J54:K200', {'type': 'icon_set',
'icon_style': '3_arrows',
'icons': [
{'criteria': '>=', 'type': 'number', 'value': 1},
{'criteria': '>=', 'type': 'number', 'value': 0},
{'criteria': '<', 'type': 'number', 'value': -1}
]}
)
This is what I have looked at :
Besides similar questions here, this is what I have done :
I looked at Excel for the formula and compared to my own work, to start from my output, and figure out the correct rule.
The closest I got so far is that when I change my icons 'value'to 2, 1, 0 respectively, I get the 1 to have the middle orange arrow:
This tells me that my equality must be correct, yet it doesn't produce the expected result.
Thanks for any help provided!
If you eliminate the {'criteria': '>=', 'type': 'number', 'value': 0}, from your code it should work fine. I have a reproducible example of this below with the expected output.
import pandas as pd
import numpy as np
#Creating a sample dataframe for example demonstration
df = pd.DataFrame({'col1': [0, -1, 10, -2], 'col2': [-11, 0, -3, 1]})
writer = pd.ExcelWriter('test.xlsx', engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1', index=False)
writer.sheets['Sheet1'].conditional_format('A2:B5', {'type': 'icon_set',
'icon_style': '3_arrows',
'icons': [
{'criteria': '>=', 'type': 'number', 'value': 0.001},
{'criteria': '<=', 'type': 'number', 'value': -0.001}
]}
)
writer.save()
Expected test.xlsx:

xlsxwriter: how "inf" value can be uncolored?

using python package "xlsxwriter", I want to highlight cells in the following conditional range;
value > 1 or value <-1
However, some cells have -inf/inf values and it fill colors them too (to yellow). Is thare any way to unhighlight them?
I tried "conditional_format" function to uncolor them, but it doesn't work.
output example
format1 = workbook.add_format({'bg_color':'#FFBF00'}) #yellow
format2 = workbook.add_format({'bg_color':'#2E64FE'}) #blue
format3 = workbook.add_format({'bg_color':'#FFFFFF'}) #white
c_fold=[data.columns.get_loc(col) for col in data.columns if col.startswith("fold")]
c_fold.sort()
l=len(data)+1
worksheet.conditional_format(1,c_fold[0],l,c_fold[-1], {'type':'cell',
'criteria' : '>',
'value':1,
'format':format1,
})
worksheet.conditional_format(1,c_fold[0],l,c_fold[-1], {'type':'cell',
'criteria' : '<',
'value':-1,
'format':format2,
})
worksheet.conditional_format(1,c_fold[0],l,c_fold[-1], {'type':'text',
'criteria' : 'begins with',
'value':"-inf",
'format':format3,
})
Thanks in advance
In a lot of cases the answer to the question "how do I get this to work with XlsxWriter" is the same as the answer to the question "how do I get this to work with Excel".
If you try your example in Excel you will see that you get the same results as the XlsxWriter example. The > criteria is applies to -inf in Excel, thus it is highlighted as light orange. The fact that the following containing criteria also matches doesn't override the first matching criteria since Excel applies them in the order that the user supplies them.
The solution in Excel, and XlsxWriter, is to change the order that the rules are applied, like this:
import xlsxwriter
workbook = xlsxwriter.Workbook('conditional_format.xlsx')
worksheet1 = workbook.add_worksheet()
# Add some formats to use in the conditional formats.
format1 = workbook.add_format({'bg_color': '#FFBF00'})
format2 = workbook.add_format({'bg_color': '#2E64FE'})
format3 = workbook.add_format({'bg_color': '#FFFFFF'})
# Write some sample data.
worksheet1.write('A1', 2)
worksheet1.write('A2', '-inf')
worksheet1.write('A3', -2)
# Write a conditional formats over the same range.
worksheet1.conditional_format('A1:A3', {'type': 'text',
'criteria': 'begins with',
'value': "-inf",
'format': format3})
worksheet1.conditional_format('A1:A3', {'type': 'cell',
'criteria': '>',
'value': 1,
'format': format1})
worksheet1.conditional_format('A1:A3', {'type': 'cell',
'criteria': '<',
'value': 1,
'format': format2})
workbook.close()
Output:
This would solve
worksheet.conditional_format(1,c_fold[0],l,c_fold[-1], {'type':'text',
'criteria' : 'containing',
'value':"-inf",
'format':format3,
})

Encountered "TypeError: integer argument expected, got float" while trying to plot a simple column chart

I'm trying to plot a simple column chart using xlsxwriter. The following is the script I wrote for the same:
import xlsxwriter
cmui = [456.0,424.08,114.0,22.8,22.8]
workbook = xlsxwriter.Workbook('first.xlsx')
worksheet = workbook.add_worksheet()
chart = workbook.add_chart({'type':'column'})
dec = workbook.add_format({'num_format':'#0.000000'})
bold = workbook.add_format()
bgc = workbook.add_format({'bold':'True'})
bgc.set_pattern(1)
bgc.set_bg_color("#DD8000")
chart.add_series({'values':cmui})
chart.set_title({'name':'Example'})
chart.set_y_axis({'name':'A'})
chart.set_x_axis({'name':'B'})
worksheet.insert_chart('A10',chart)
workbook.close()
When I try and execute the above, I'm getting the error:
TypeError: integer argument expected, got float
Which is understandably because I'm passing a list with floating type values inside. But does this mean I cannot plot floating point values at all or is there a workaround for this?
The chart.add_series() values property doesn't take a list of data values like that you should write the data to the worksheet and reference it. Like this:
worksheet.write_column('A1', cmui)
chart.add_series({'values': 'Sheet1!A1:A5'})
The list parameter for values is used specify a the range dimensions so that you don't have to programmatically generate an Excel range like Sheet1!A1:A5:
chart.add_series({'values': ['Sheet1', 0, 0, 4, 0]})
You're getting it wrong. According to the docs:
chart.add_series({
'categories': '=Sheet1!$A$1:$A$5',
'values': '=Sheet1!$B$1:$B$5',
'line': {'color': 'red'},
})
# Or using a list of values instead of category/value formulas:
# [sheetname, first_row, first_col, last_row, last_col]
chart.add_series({
'categories': ['Sheet1', 0, 0, 4, 0],
'values': ['Sheet1', 0, 1, 4, 1],
'line': {'color': 'red'},
})
The add_series() function accepts the coordinates of spreadsheet cells, not the exact values, so you need to insert your values into the spreadsheet and then only specify thier coordinates in values.
Use set_num_format('0.00')
See examples in the link below:
http://xlsxwriter.readthedocs.org/format.html

Categories