如何解决python破折号表条件格式色标
我想按色标按值从高到小对列着色 像这样
当前,我在函数中创建破折号表,并通过循环将其发送给每一列;
def make_table_in_div(df,column_name):
pv = pd.pivot_table(df,index=[column_name],values=['val1'],aggfunc=['mean','count']).reset_index()
pv.columns = [column_name,'val1','count']
print(column_name)
div = html.Div([html.H1(column_name),dash_table.DataTable(
columns=[{"name": i,"id": i} for i in pv.columns],data=pv.to_dict('records'),)],style={'height': 30,'margin-right': 'auto','margin-left': 'auto','width': '800px'}) # 'width': '50%',return div
div = [make_table_in_div(df,column_name) for column_name in ['column_name']]
return div
破折号表看起来像是流动的图片,我想给value列上色
解决方法
这是可能的。您应该查看以下链接:https://dash.plotly.com/datatable/conditional-formatting 特别是“在单个列上用色标突出显示”部分
我为您写了一个简单的例子:
import dash
import dash_table
import pandas as pd
import dash_html_components as html
import colorlover
from jupyter_dash import JupyterDash
# Dash Application
df = pd.DataFrame(list(zip(
[5,6,7,8,9,10,11,12,13,14],[0.328,0.323,0.193,0.231,0.216,0.284,0.250,0.258,0.394,0.455],[67,99,109,104,88,74,32,31,33,22]
)),columns=['column_name','value','count'])
app = JupyterDash(__name__)
# Function for styling table,defined below
cols = ['value']
(styles,legend) = discrete_background_color_bins(df,columns = cols)
app.layout = html.Div([
legend,dash_table.DataTable(
id = 'table',columns = [{"name": i,"id": i} for i in df.columns],data = df.to_dict('records'),style_data_conditional = styles
)
])
app.run_server(mode='inline')
此函数使用给定的色标为指定列的每一行返回样式列表。
要获得色标,您需要使用pip install colorlover
其他色阶可以在这里找到:https://github.com/plotly/colorlover
# Function for styling the table
def discrete_background_color_bins(df,n_bins=7,columns='all'):
bounds = [i * (1.0 / n_bins) for i in range(n_bins+1)]
if columns == 'all':
if 'id' in df:
df_numeric_columns = df.select_dtypes('number').drop(['id'],axis=1)
else:
df_numeric_columns = df.select_dtypes('number')
else:
df_numeric_columns = df[columns]
df_max = df_numeric_columns.max().max()
df_min = df_numeric_columns.min().min()
ranges = [
((df_max - df_min) * i) + df_min
for i in bounds
]
styles = []
legend = []
for i in range(1,len(bounds)):
min_bound = ranges[i - 1]
max_bound = ranges[i]
backgroundColor = colorlover.scales[str(n_bins+4)]['div']['RdYlGn'][2:-2][i - 1]
color = 'black'
for column in df_numeric_columns:
styles.append({
'if': {
'filter_query': (
'{{{column}}} >= {min_bound}' +
(' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '')
).format(column=column,min_bound=min_bound,max_bound=max_bound),'column_id': column
},'backgroundColor': backgroundColor,'color': color
})
legend.append(
html.Div(style={'display': 'inline-block','width': '60px'},children=[
html.Div(
style={
'backgroundColor': backgroundColor,'borderLeft': '1px rgb(50,50,50) solid','height': '10px'
}
),html.Small(round(min_bound,2),style={'paddingLeft': '2px'})
])
)
return (styles,html.Div(legend,style={'padding': '5px 0 5px 0'}))
,
感谢The answer of Kristian Haga。 -效果很好。
我想为与我有相同问题的未来用户总结选项。当我们想在多列上运行它时,有两个选择:
-
原始函数将对所有具有相同比例(最小和最大)的列进行着色,因此,如果我运行多个列(来自示例:值和计数),则它将返回基于min范围着色的表格样式所有列中的最大值和最大值(来自示例:0.193,109)。
discrete_background_color_bins(df,columns=['value','count'])
def discrete_background_color_bins(df,columns='all'): bounds = [i * (1.0 / n_bins) for i in range(n_bins+1)] if columns == 'all': if 'id' in df: df_numeric_columns = df.select_dtypes('number').drop(['id'],axis=1) else: df_numeric_columns = df.select_dtypes('number') else: df_numeric_columns = df[columns] df_max = df_numeric_columns.max().max() df_min = df_numeric_columns.min().min() ranges = [ ((df_max - df_min) * i) + df_min for i in bounds ] styles = [] legend = [] for i in range(1,len(bounds)): min_bound = ranges[i - 1] max_bound = ranges[i] backgroundColor = colorlover.scales[str(n_bins+4)]['div']['RdYlGn'][2:-2][i - 1] color = 'black' for column in df_numeric_columns: styles.append({ 'if': { 'filter_query': ( '{{{column}}} >= {min_bound}' + (' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '') ).format(column=column,'column_id': column },'color': color }) legend.append( html.Div(style={'display': 'inline-block',children=[ html.Div( style={ 'backgroundColor': backgroundColor,'height': '10px' } ),style={'paddingLeft': '2px'}) ]) ) return (styles,style={'padding': '5px 0 5px 0'}))
-
如果我们要根据每列的最小值和最大值分别给它上色, 我们将使用以下功能:
(非常相似,但首先在列上运行)def discrete_background_color_bins(df,columns='all'): bounds = [i * (1.0 / n_bins) for i in range(n_bins+1)] if columns == 'all': if 'id' in df: df_numeric_columns = df.select_dtypes('number').drop(['id'],axis=1) else: df_numeric_columns = df.select_dtypes('number') else: df_numeric_columns = df[columns] df_max = df_numeric_columns.max().max() df_min = df_numeric_columns.min().min() ranges = [ ((df_max - df_min) * i) + df_min for i in bounds ] styles = [] legend = [] for i in range(1,len(bounds)): min_bound = ranges[i - 1] max_bound = ranges[i] backgroundColor = colorlover.scales[str(n_bins+4)]['div']['RdYlGn'][2:-2][i - 1] color = 'black' for column in df_numeric_columns: styles.append({ 'if': { 'filter_query': ( '{{{column}}} >= {min_bound}' + (' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '') ).format(column=column,'column_id': column },'color': color }) legend.append( html.Div(style={'display': 'inline-block',children=[ html.Div( style={ 'backgroundColor': backgroundColor,'height': '10px' } ),style={'paddingLeft': '2px'}) ]) ) return (styles,style={'padding': '5px 0 5px 0'}))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。