Reducing a List of Lists - python-3.x

I have this pretty un-sightly list below of length 3:
[([('euw1', 12700)], [('la2', 1800)]),
([('kr', 7500), ('br1', 4700), ('jp1', 400), ('sg2', 100)], [('vn2', 1200), ('oc1', 600)]),
([('na1', 5400), ('eun1', 3900), ('la1', 2300), ('tr1', 900),('ph2', 200)], [('tw2', 700), ('ru', 400), ('th2', 100)])]
Ideally I would like my list to be flattened into the form:
[[('euw1', 12700), ('la2', 1800)],
[('kr', 7500), ('br1', 4700), ('jp1', 400), ('sg2', 100),('vn2', 1200),('oc1', 600)],
[('na1', 5400), ('eun1', 3900), ('la1', 2300), ('tr1', 900),('ph2', 200),('tw2', 700), ('ru', 400), ('th2', 100)]]
Does anybody know how I might go about this, ideally using as little packages as possible?

You can use more_itertools.flatten.
from more_itertools import flatten
lst = [
([('euw1', 12700)], [('la2', 1800)]),
([('kr', 7500), ('br1', 4700), ('jp1', 400), ('sg2', 100)], [('vn2', 1200), ('oc1', 600)]),
([('na1', 5400), ('eun1', 3900), ('la1', 2300), ('tr1', 900),('ph2', 200)], [('tw2', 700), ('ru', 400), ('th2', 100)])
]
[list(flatten(el)) for el in lst]
Output:
[[('euw1', 12700), ('la2', 1800)],
[('kr', 7500),
('br1', 4700),
('jp1', 400),
('sg2', 100),
('vn2', 1200),
('oc1', 600)],
[('na1', 5400),
('eun1', 3900),
('la1', 2300),
('tr1', 900),
('ph2', 200),
('tw2', 700),
('ru', 400),
('th2', 100)]]

Related

Can we use torch.multiprocessing.spawn with wandb sweep hyper-parameter tuning?

Can we use torch.multiprocessing.spawn with wandb.sweep (https://docs.wandb.ai/guides/sweeps).
torch.multiprocessing.spawn(func, nprocs=world_size, join=True)
I tried but got errors and cannot find tutorials.
I am using Python's standard multiprocessing library to spawn agents for a wandb.sweep:
import multiprocessing
import wandb
def init():
'''set up config and start sweep'''
sweep_config = {
'method': 'grid',
'name': 'sweep',
'metric': {
'goal': 'minimize',
'name': 'val_loss'
},
'parameters': {
'net': {'values': ['unet', 'swinunetr']},
'batch_size': {'values': [1, 16, 32, 64, 128]},
'lr': {'values': [1e-1, 1e-2, 1e-3, 1e-4, 1e-5]},
'patch_size': {'values': [32, 64, 128, 256]},
'samples_per_slice': {'values': [1, 2, 4, 8, 16]}
}
}
# count num of combinations for grid sweep
sweep_count = 1
for key in sweep_config['parameters']:
sweep_count *= len(sweep_config['parameters'][key]['values'])
sweep_id = wandb.sweep(sweep=sweep_config, project='proj', )
return sweep_id, sweep_count
def main():
'''training code goes here'''
# connect agent to sweep and import configs/params
wandb.init()
config = {
'net': wandb.config.net,
'batch_size': wandb.config.batch_size,
'lr': wandb.config.lr,
'patch_size': wandb.config.patch_size,
'samples_per_slice': wandb.config.samples_per_slice,
}
print(config)
wandb.log(config)
### ADD YOUR TRAINING CODE HERE
def agent(sweep_id, sweep_count):
'''run agent'''
wandb.agent(sweep_id, function=main, count=sweep_count, project='proj')
if __name__ == '__main__':
# initialize sweep
sweep_id, sweep_count = init()
# spawn and run 4 agents for the sweep
procs = []
for _ in range(4):
p = multiprocessing.Process(target=agent, args=[sweep_id, sweep_count])
p.start()
procs.append(p)
for p in procs:
p.join()
This dumps all wandb logs into a single terminal window, which I haven't yet figured out.

Capture which items are displayed on Python Plotly Express chart based on legend selection

DISTRIB_DESCRIPTION="Ubuntu 20.04.5 LTS"
Streamlit, version 1.12.2
plotly==5.10.0
I have a Plotly Express px.scatter chart being generated in a Streamlit page. The different data points available to be shown are set by the color= parameter in ...
fig = px.scatter(x=df[x_column_name],
y=df[y_column_name],
color=df[color_column_name])
Which data (color) points are actually shown on the chart can be selected in the legend (see images.)
Is there a way to detect in the code (via the fig or something else) which data points (colors) have actually been selected in the legend to appear on the chart? I.e. In the example pictures, for the Streamlit (Python) code to know that only DMP, OTP, and BP are currently being seen on the plotly chart?
All selected
None selected
DMP, OTP, BP selected
FULL CODE
def control_chart_by_compound(df,
x_column_name,
y_column_name,
color_column_name,
chart_width = 800,
marker_line_width = 1,
standard_deviation = False,
stddev_colors = ["#CCFF00","#FFCC99","#FF9966"],
average = False,
average_color = "green",
custom_marker_lines = [],
custom_marker_lines_colors = []
):
if custom_marker_lines_colors == []:
custom_marker_lines_colors = CSS_blues()
fig = px.scatter(x=df[x_column_name],
y=df[y_column_name],
color=df[color_column_name],
width=chart_width,
labels={
"x": x_column_name,
"y": y_column_name,
color_column_name: "Compounds"
},
)
# Adds buttons select or deselect all amongst the legend (default the compounds as different colors)
fig.update_layout(dict(updatemenus=[
dict(
type = "buttons",
direction = "left",
buttons=list([
dict(
args=["visible", "legendonly"],
label="Deselect All compounds",
method="restyle"
),
dict(
args=["visible", True],
label="Select All compounds",
method="restyle"
)
]),
pad={"r": 10, "t": 10},
showactive=False,
x=1,
xanchor="right",
y=1.1,
yanchor="top"
),
]
))
if average != False:
fig.add_hline(y=np.average(df[y_column_name]),
line_color=average_color,
line_width=marker_line_width,
line_dash="dash")
# Add zero hline
fig.add_hline(y=0, line_color="gainsboro")
### Standard deviations
if standard_deviation != False:
stddev = df[y_column_name].std()
for idx, color in enumerate(stddev_colors):
fig.add_hline(y=stddev * (idx+1), line_color=color, line_width=marker_line_width,)
fig.add_hline(y=-stddev * (idx+1), line_color=color, line_width=marker_line_width,)
for idx, line in enumerate(custom_marker_lines):
fig.add_hline(y=line, line_color=custom_marker_lines_colors[idx], line_width=marker_line_width,)
fig.add_hline(y=-line, line_color=custom_marker_lines_colors[idx], line_width=marker_line_width,)
# Background to clear
fig.update_layout({
'plot_bgcolor': 'rgba(0, 0, 0, 0)',
'paper_bgcolor': 'rgba(0, 0, 0, 0)',
})
fig.update_layout(xaxis=dict(showgrid=False),
yaxis=dict(showgrid=False))
return fig

How to combine two x axes using subplot

I have two plots (candle and bar). I want to combine them in the same subplot (x-axes in the top for volume and x-axes at the bottom for dates), but when I try to combine both in the same subplot (row=2, col=1), the result it's not the expected.
import plotly from plotly
import subplots
import random
import pandas as pd
import plotly.graph_objects as go
fig = make_subplots(rows=3, cols=2)
high = 40
low = 5
dev = 1
days = 18
fake_market = []
for each in range(days):
ohlc = []
ohlc.append(each)
if each == 0:
o = random.randrange(low, high)
ohlc.append(o)
else:
ohlc.append(c) #I know
h = random.randrange(o, high)
ohlc.append(h)
l = random.randrange(low, o)
ohlc.append(l)
c = random.randrange(l, h)
ohlc.append(c)
fake_market.append(ohlc)
fake_volume = [[x, random.randrange(1, 200)] for x in range(low, (high+1))]
df = pd.DataFrame(fake_market, columns=["Date", "Open", "High", "Low", "Close"])
df2 = pd.DataFrame(fake_volume, columns=["Volume", "Price"])
fecha = ['2019-03-22', '2019-03-23', '2019-03-24', '2019-03-25',
'2019-03-26', '2019-03-27', '2019-03-28', '2019-03-29',
'2019-03-30', '2019-03-31', '2019-04-01', '2019-04-02',
'2019-04-03', '2019-04-04', '2019-04-05', '2019-04-06',
'2019-04-07', '2019-04-08']
candle =go.Candlestick(
x=fecha,
open=[str(x) for x in df.Open.to_list()],
high=[str(x) for x in df.High.to_list()],
low=[str(x) for x in df.Low.to_list()],
close=[str(x) for x in df.Close.to_list()],
visible=True,
showlegend=True,
xaxis='x3',
yaxis ='y3')
vol_bar = go.Bar(
x=[str(x) for x in df2.Price.to_list()],
y=[str(x) for x in df2.Volume.to_list()],
xaxis='x4',
yaxis ='y4',
name='volume',
orientation="h",
opacity=0.4, marker=dict(
color='rgba(246, 78, 139, 0.6)', line=dict(color='rgba(246, 78, 139, 1.0)', width=0.1)))
fig.add_trace(candle, row=2, col=1)
fig.add_trace(vol_bar, row=2, col=1)
fig.update_layout(
yaxis3=dict(
title="yaxis3 title",
titlefont=dict(
color="#1f77b4"
),
tickfont=dict(
color="#1f77b4"
)
),
yaxis4=dict(
title="yaxis4 title", side='right',
titlefont=dict(
color="#1f77b4"
),
tickfont=dict(
color="#1f77b4"
)
),
xaxis3=dict(
title="xaxis3 volume", side='top', overlaying='x',
titlefont=dict(
color="#9467bd"
),
tickfont=dict(
color="#9467bd"
)),
xaxis4=dict(
title="xaxis4 date", side='bottom',
titlefont=dict(
color="#9467bd"
),
tickfont=dict(
color="#9467bd"
))
)
fig.update_xaxes(rangeslider_visible=False)
fig.show()
The plots are showed as follow:
The plots:
The result: The result:
The plot expected: The plot expected:
Apparently the x axes are mixing and that is the reason for getting a distorted graph is obtained.

font.getsize() seems not to work with "\n" (new lines) inside the parameter

The used font: https://www.fontspace.com/abeezee-font-f30774
ImageFont.truetype(*path/to/font*, 300)
font.getsize("1\n\r0\n\r9") # returns: (1080, 280) which is wrong!
image = np.full(shape=(1, 1, 3), fill_value=0, dtype=np.uint8)
image = Image.fromarray(image, mode="RGB")
draw = ImageDraw.Draw(image)
draw.multiline_textsize(text="1\n\r0\n\r9", font=font, spacing=0) # returns: (180, 837) which is correct"
Why are the results different? What am I missing?
So The main error was:
1) for multiline text we should use:
PIL.ImageDraw.ImageDraw.multiline_text(xy, text, fill=None, font=None, anchor=None, spacing=0, align="left", direction=None, features=None, language=None)
In addition .getsize() returned a height that is a little too big. The height that worked for me was:
font.getmask(digit).size[1]
wich is the same to:
font.getsize(digit)[1] - font.getoffset(digit)[1]

Plotly Waterfall Chart Stacked in Python

All,
I can create a nice little waterfall chart using the code below. However, I would like to be able to split the data to show contributions to that specific metric.
For example I would like to split the waterfall bars by Local and International. ie. the Sales would have both Local and International adding up to the total. Can this be done.
import plotly.graph_objects as go
fig = go.Figure(go.Waterfall(
name = "20", orientation = "v",
measure = ["relative", "relative", "total", "relative", "relative", "total"],
x = ["Sales", "Consulting", "Net revenue", "Purchases", "Other expenses", "Profit before tax"],
textposition = "outside",
text = ["+60", "+80", "", "-40", "-20", "Total"],
y = [60, 80, 0, -40, -20, 0],
connector = {"line":{"color":"rgb(63, 63, 63)"}},
))
fig.update_layout(
title = "Profit and loss statement 2018",
showlegend = True
)
fig.show()

Resources