Cell Colors Using OpenPyxl 2.02 - colors

I've just upgraded from openpyxl 1.6.2 to 2.02, and have a question regarding setting cell colors.
The Styles function should handle all the necessary formatting, and that includes using the Fill function to set the cell color. This latter function has fill_type as one of its arguments. How do you set this to a solid fill? In previous versions, this was done using something like:
mycell.style.fill.fill_type = Fill.FILL_SOLID
The documentation, which looks like it's in progress, seems to suggest that setting fill_type = Fill.FILL_SOLID will do the trick (scroll down to the notes at the bottom of the page). But I'm getting an AttributeError when trying it.
from openpyxl.styles import Fill, Color
from openpyxl.styles.colors import RED
redfill = Fill(fill_type=Fill.FILL_SOLID,start_color=RED)
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
redfill = Fill(fill_type=Fill.FILL_SOLID,start_color=RED)
AttributeError: type object 'Fill' has no attribute 'FILL_SOLID'
Any thoughts?

A style is immutable once created, you have to construct a new one and assign it to the cell style property like this:
mycell.style = Style(fill=PatternFill(patternType='solid', fgColor=Color('FFFF0000')))
this will turn the cell red.

Constants are now module and not class constants.
from openpyxl.styles import fills, PatternFill
fill = PatternFill(patternType=fills.FILL_SOLID)
Though I think it's easier just to use patternType='solid'

Related

How to embed a dropdown ipywidget in an ipysheet spreadsheet?

I tried following the code to merge a dropdown menu ipywidget into the ipysheet. it seems like my code works the way I imagined. However, I am unable to select items from the menus listed in the dropdown widget.
import ipysheet
import ipywidgets as widgets
Solvent = widgets.Dropdown(
options=['DMC', '2-Butanol', 'Chloroform', 'Ethanol'],
value='DMC',)
sheet2 = ipysheet.sheet()
ipysheet.column(0, [Solvent])
ipysheet.column(1, [1,2,3,4, 5])
widgets.VBox([sheet2, Solvent ])
After some review, I believe that this is a genuine bug/shortcoming with ipysheet. Though there are alternative approaches, this inability to use a particular widget within ipysheet cells is not an expected result of this API... Someone please correct me if I'm missing something.
There is a "hack" that is working for me through Jupyter Notebook in the browser, which is to right-click the dropdown before left-clicking it to change the context of the dropdown menu, allowing you to select it via mouseover.
The other alternative is passing in your options as the "choice" argument to the cell you wish to contain the dropdown.
from ipywidgets import link
import ipysheet
import ipywidgets as widgets
Solvent = widgets.Dropdown(
options=['DMC', '2-Butanol', 'Chloroform', 'Ethanol'],
value='DMC',)
sheet2 = ipysheet.sheet()
# dropdown_cell = ipysheet.cell(0,0,choice = Solvent.options,value='WORLD')
interactive_cell = ipysheet.cell(1,3, value='HELLO')
dropdown_cell = ipysheet.cell(0,0,choice = Solvent.options,value='WORLD')
# link((interactive_cell,'value'),(dropdown_cell,'value'))
link((dropdown_cell,'value'),(interactive_cell,'value'))
widgets.VBox([sheet2, Solvent ])
From my current understanding (and attempts), only cells are interactive in ipysheets. (The alternative method of using the ipysheet "calculation" decorator also depends on the items being Cells, not Columns.)

How to manually set a diverging color range

I am using Altair for Python and my current code uses a redyellowblue color scheme which uses the middle color (yellow) accordingly to my domainMid parameter.
color=alt.Color('Spline_WW_Diff_Trend:Q', scale=alt.Scale(scheme='redyellowblue',reverse=True, domain=[-3.57,2.270], domainMid=0, clamp=True), legend=alt.Legend(title="Trend"))
Which gives me:
I need to replace the yellow color with the white color. I've switched scheme to range and tried different combinations of Scale parameters, but it doesn't respect my domainMid.
Example:
color=alt.Color('Spline_WW_Diff_Trend:Q', scale=alt.Scale(range=['#D4322C', 'white', '#4A74B4'],reverse=True, domain=[-3.57,2.270], domainMid=0, clamp=True), legend=alt.Legend(title="Trend"))
This gives me:
You can notice that the first column (which is all value 0) is showing reddish and not white (as it was supposed to be).
How can I have the same result as in the color scheme (picture one), but, with white instead of yellow?
Edit:
The same goes for.
range=['blue', 'lightblue', 'white', 'pink', 'red']
The mid color is light-blue, not white.
Edit 05/12/2022:
Just to clarify, I would like to achieve this same color scheme:
.
This heatmap was created in R, by using the RdYlBu color pallete (the one with 11 colors) and overwrite the middle (6th color) with white. Then, they increased the number of colors in the pallete to 99, to make the fade look more fluid. Does anyone has any idea on how to achieve that in Altair?
The easiest approach would be to set range='diverging', or to use one of the built-in diverging color schemes. For example:
import altair as alt
import pandas as pd
import numpy as np
df = pd.DataFrame({'x': np.arange(-10, 20)})
alt.Chart(df).mark_rect().encode(
x='x:O',
color=alt.Color('x:Q',
scale=alt.Scale(domainMid=0, scheme='redblue'))
)
If it's important to you that the center value is exactly white, you could use a condition to override the colormap for this value. For example:
alt.Chart(df).mark_rect().encode(
x='x:O',
color=alt.condition(
'datum.x == 0',
alt.value('white'),
alt.Color('x:Q', scale=alt.Scale(domainMid=0, scheme='redblue')))
)

I want to draw diagonal lines to Excel cells with openpyxl module in python

When I execute my source, top, bottom, left, and right are applied border_style but the rest are not.
(I wanted to attach it as an image, but I can not fill 10 reputations yet and attach it as a link.)
"when I execute source"
and This is the result I want
"I expect"
I also try to use diagonalUp=True, diagonalDown=True but It didn't work
I do not know what options I need to set up.
from openpyxl.styles import Border, Side
import openpyxl
wb = openpyxl.Workbook()
ws = wb.active
ws['B2'] = "test"
ca2 = ws['B2']
box = Border(left=Side(border_style="thin",color='FF000000'),
right=Side(border_style=None,color='FF000000'),
top=Side(border_style="double",color='FF000000'),
bottom=Side(border_style=None,color='FF000000'),
diagonal=Side(border_style="thin",color='FF000000'),
diagonal_direction=0,
outline=Side(border_style="double",color='FF000000'),
vertical=Side(border_style="double",color='FF000000'),
horizontal=Side(border_style="double",color='FF000000')
)
ca2.border = box
wb.save("test.xlsx")
The main issue is that I want to know why diagonal does not work. If you can afford it, I would like to know why outline, vertical, and horizontal are not working. Probably my usage is wrong and I guess these things do not work.
It looks like you need to explicitly set the direction of the diagonal. For top-left to bottom right use box.diagonalDown=True and for bottom-left to top-right use box.diagonalUp=True.

Conditionally Color Table Cells with ReportLab

I've created a table using ReportLab. I would like to conditionally color the cells, depending on their contents (in my case, I want negative numbers to be red). To be clear, I have the conditional code working, I can't figure out how to add color. What I've tried:
using the <font color="..."> tag. Instead, the tags is included verbatim in the output.
wrapping each cell in Paragraph(...) (suggested in this answer). In this case, the cell text is linewrapped after each letter.
wrapping the table in Paragraph(...). In this case, reportlab errors out (I believe the resulting error was TypeError: split() missing required positional argument: 'availHeight')
I found reportlab.platypus.tables.CellStyle in the reportlab source code, but can't figure out make use of it. Google turns up nothing useful and it's not mentioned in the reportlab documentation.
I guess TableStyle(...) rules could be used, but the cells aren't in a predetermined position within the table (which is what all the examples assume).
Help appreciated!
Using TableStyle() would be an acceptable solution. You could loop through the data and add a style command when the condition is met.
Here is an example:
import random
from reportlab.lib.pagesizes import letter
from reportlab.lib.colors import red
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
# Generate random data with positive and negative values as list of lists.
data = []
for _ in range(20):
data.append(random.sample(range(-10, 10), 5))
table_style = TableStyle([('ALIGN', (0, 0), (-1, -1), 'RIGHT')])
# Loop through list of lists creating styles for cells with negative value.
for row, values, in enumerate(data):
for column, value in enumerate(values):
if value < 0:
table_style.add('TEXTCOLOR', (column, row), (column, row), red)
table = Table(data)
table.setStyle(table_style)
pdf = SimpleDocTemplate('example.pdf', pagesize=letter)
pdf.build([table])

How do I set custom colours on a pyqt QColorDialog?

I am bringing up a QcolorDialog like so:-
colour = QtGui.QColorDialog.getColor()
What I want to know is how to set the colours of the custom color swatches before I bring up the dialog. I have searched a lot and found the method setCustomColor() but I just can't get it to work. It repeatedly tells me
TypeError: argument 2 of QColorDialog.setCustomColor() has an invalid type
I have tried all manner of variations of how to create a QColor, but it never seems happy with it.This is what I am currently trying:-
mycolor = QtGui.QColor(0,0,0,0)
colour = QtGui.QColorDialog.setCustomColor(0,mycolor)
But it still gives me the same 'invalid type' error...
Any ideas?
All you need to do is:
colour_dia = QtGui.QColorDialog()
mycolour = QtGui.QColor(0, 0, 0, 0).rgba()
#This needs a integer value for colour
colour_dia.setCustomColor(0, mycolour)
selected_colour = colour_dia.getColor()

Resources