Print table in plotly dash with multiple lines in one cell - python-3.x

Currently I have a pandas dataframe :
df = pd.DataFrame({
"date": ["20210613", "20210614", "20210615"],
"user": ["A\nB", "C", "D"],
"machine" : [1, 0, 3]
})
I wonder if there is any way to print this table to my dash app like this:
no matter using pure text print into dcc.Textarea or dash_table.DataTable are fine.
Currently I still can not figure out a good way to achieve this, many thanks.

You can do it in a DataTable by using the style_cell property on the DataTable like this:
import dash
import dash_table
import pandas as pd
df = pd.DataFrame(
{
"date": ["20210613", "20210614", "20210615"],
"user": ["A\nB", "C", "D"],
"machine": [1, 0, 3],
}
)
app = dash.Dash(__name__)
app.layout = dash_table.DataTable(
id="table",
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict("records"),
style_cell={"whiteSpace": "pre-line"},
)
if __name__ == "__main__":
app.run_server(debug=True)
You can make the datatable cells break when they encounter the \n character by setting the white-space CSS attribute for the cells in the table
I found this answer on this thread

Related

Pivot Tables in Python have different formatting comparing to Excel

Let's say we have a dataframe that looks like this:
I want to use pandas pivot table to format it in this way:
.
However, df.pivot_table(index='Groupings', columns='columns', values=['value1','value2']) gives me an output that looks like this:
Does anyone know how to solve this problem?
You can use the following code to create the df
import pandas as pd
data = {"Groupings": ["item1", "item1", "item1", "item2", "item2", "item3", "item3"],
"columns": ["A", "B", "C", "A", "B", "C", "D"],
"value1": [1,2,3,4,5,6,7],
"value2": [11,22,33,44,55,66,77],}
df = pd.DataFrame(data)
df

Using width="container" in an altair chart saved as html

I am trying to use the feature width="container" that allows the width of the chart to be the same as parent container in a saved chart. The rendered chart does not use the width defined in the parent div. See the reprex below.
>>> import altair as alt
>>> import pandas as pd
>>> from altair_saver import save
>>> df = pd.DataFrame(
... {
... "x": range(6),
... "y": range(6, 0, -1),
... "category": ["A", "B", "A", "B", "A", "B"],
... }
... )
...
>>> chart = alt.Chart(df, width="container").mark_line().encode(x="x:Q", y="y:Q", color="category:N")
>>> chart_html = save(chart, fmt="html", method="html", standalone=False)
>>> html = f"<html><head></head><body><div style='width: 500px'>{chart_html}</div></body></html>"
>>> with open("test_save.html", "w") as f:
... f.write(html)
...
>>> alt.__version__
'4.1.0'
>>> from altair_saver import __version__
>>> __version__
'0.5.0'
The rendered chart is very small, and if I change the size of the window in any way, the chart grows.
Maybe there is something I do not understand or use incorrectly. I want the chart rendered as HTML as I am not in a notebook environment.

Python Dash Data Table should display only selected columns

I am trying to display only selected columns from my dataframe using datatable . i am able select how many rows i want . looking for a similar option like rows i want to select to display certain columns alone at the time of executing the code.
My dataframe has close to 25 columns . i dont want all of them to be displayed hence looking for this solution
here is my code :
import dash
import dash_core_components as dcc
import dash_bootstrap_components as dbc
import dash_html_components as html
import dash_table as dt
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import plotly.express as px
import pandas as pd
df = pd.read_csv('E:\pylab\dshlab\infratickets.csv', low_memory = False )
app = dash.Dash(__name__)
#style={'visibility': 'hidden'}
dpdown = []
for i in df['ASSIGNED_GROUP'].unique() :
str(dpdown.append({'label':i,'value':(i)}))
app.layout = html.Div([
html.P([
html.Label("Choose a feature"),
html.Div(dcc.Dropdown(id='dropdown', options=dpdown),
style = {'width': '100px',
'fontSize' : '10px',
'padding-left' : '100px',
'display': 'inline-block'})]),
#style={'visibility': 'hidden'},
html.Div(id='table-container', className='tableDiv'),
dcc.Graph(id = 'plot',style={'height' : '25%', 'width' : '25%'})
])
#dcc.Dropdown(id='dropdown', style={'height': '30px', 'width': '100px'}, options=dpdown),
#dcc.Graph(id='graph'),
#html.Div(html.H3('country graph'),id='table-container1',className='tableDiv1')
#app.callback(
dash.dependencies.Output('table-container','children'),
[dash.dependencies.Input('dropdown', 'value')])
def display_table(dpdown):
df_temp = df[df['ASSIGNED_GROUP']==dpdown]
return html.Div([
dt.DataTable(
id='main-table',
columns=[{'name': i, 'id': i} for i in df_temp.columns],
data=df_temp[0:5].to_dict('rows'),
style_table={
'maxHeight': '20%',
#'overflowY': 'scroll',
'width': '30%',
'minWidth': '10%',
},
style_header={'backgroundColor': 'rgb(30, 30, 30)'},
style_cell={'backgroundColor': 'rgb(50, 50, 50)','color': 'white','height': 'auto','width': 'auto'},#minWidth': '0px', 'maxWidth': '180px', 'whiteSpace': 'normal'},
#style_cell={'minWidth': '120px', 'width': '150px', 'maxWidth': '180px'},
style_data={'whiteSpace': 'auto','height': 'auto','width': 'auto'}
)
])
if __name__ == '__main__':
app.run_server(debug=True)
Able to figure out the solution
changed the code
columns=[{'name': i, 'id': i} for i in df_temp.columns]
to
columns=[{'name': i, 'id': i} for i in df.loc[:,['Colname1','Colname2',...]
fixed it
You could also use by index:
df = pd.read_csv('E:\pylab\dshlab\infratickets.csv', low_memory = False ) # load in the dataframe, then ressign with just the columns you want
df = df.iloc[:,1:3] # Remember that Python does not slice inclusive of the ending index.
Would give all rows and columns 1 to 2 of the data frame.
You can change the
columns=[{'name': i, 'id': i} for i in df_temp.columns],
as below:
First define TABLE_SELECTED_COLUMNS = ['col1','col2'. ...]
and
columns=[{"name": i, "id": i} for i in TABLE_SELECTED_COLUMNS],

Remove bars with 0 height in a bar graph in dash

I am trying to make a group bar graph in dash, I am plotting subject codes on the x-axis so they are not continuous numbers and I am getting empty bars for the missing subject codes so is there any way to remove these spaces or invisible bars.
This is the bar graph I am getting.
This is my code.
df = pd.read_csv('sampledata.csv')
a=df['SiteCode'].loc[df['SubjectStatus']=='In Progress'].value_counts()
a.index=a.index.astype(str)
b=df['SiteCode'].loc[df['SubjectStatus']=='Withdrawn'].value_counts()
b.index=b.index.astype(str)
x1=a.index
x2=b.index
trace1=go.Bar(
x=x1,
y=a.values,
name='In Progress',
)
trace2=go.Bar(
x=x2,
y=b.values,
name='Withdrawn',
)
app = dash.Dash()
app.layout = html.Div(
dcc.Graph(id='graph',
figure=go.Figure(data=[trace1,trace2],layout=go.Layout(barmode='group')))
if __name__=='__main__':
app.run_server()
Thanks in advance
PS: I am a noob in dash and python both so go easy on me.
You should try set barmode='stack', because barmode='group' added empty space if your one of your traces have empty values.
import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
import plotly
import plotly.graph_objs as go
import pandas as pd
app = dash.Dash(__name__)
df = pd.DataFrame({'x': [100, 100, 105, 110, 110, 115, 120, 125],
'y': [1, 2, 1, 1, 2, 2, 1, 1]})
colors = {
'background': '#111111',
'background2': '#FF0',
'text': '#7FDBFF'
}
df1 = df.loc[df["y"] == 1]
df2 = df.loc[df["y"] == 2]
trace1 = go.Bar(
x=df1["x"],
y=df1["y"],
name='In Progress',
)
trace2 = go.Bar(
x=df2["x"],
y=df2["y"],
name='Withdrawn',
)
app.layout = html.Div(children=[
html.Div([
html.H5('ANNx'),
dcc.Graph(
id='cx1',
figure=go.Figure(data=[trace1, trace2],
layout=go.Layout(barmode='group')))],)])
if __name__ == '__main__':
app.run_server(debug=True)
For example, in this code at value 105, 115 and 120 one trace is empty and this create space in plot:
Using another barmode solved this problem:

How can count different duplicates

I shared code below;
I want delete duplicates and count them.Also want a column for count times.
So clearly that code will count A column and count,delete duplicates.Finally it will add as a new column. Is it possible somehow?
df = pd.DataFrame({"A":["foo", "foo", "foo", "bar"]})
df = pd.DataFrame({"A":["foo","bar"], "B":[3,1]})
While completely not using pandas, you could achieve this using Counter from standard collections:
>>> from collections import Counter
>>> Counter(["foo", "foo", "foo", "bar"])
>>> counter = Counter(["foo", "foo", "foo", "bar"])
>>> counter.keys()
dict_keys(['foo', 'bar'])
>>> counter.values()
dict_values([3, 1])
So, for your case:
counter = Counter(["foo", "foo", "foo", "bar"])
df = pd.DataFrame({"A": list(counter.keys()), "B": list(counter.values())})

Resources