2

Creating 12 subplots with plotly from a csv containing rows with 13 values. The last value indicates that the data in that row is estimated from this point until the status changes back in a later row.
Trying to make line graphs that plots a line, changes to red when the status changes to 1, then back to original color when the status changes back to 0. Is this possible?

with lock:
    df = pd.read_csv(OCcsvFile, delimiter=',')

# plotly setup
plot_rows = 4
plot_cols = 3
# Create plot figure
fig = make_subplots(rows=plot_rows, cols=plot_cols, subplot_titles=("Header1", "Header2", "Header3", "Header4", "Header5",
                                                                    "Header6", "Header7", "Header8", "Header9", "Header10",
                                                                    "Header11", "Header12"))

# add traces
x = 1  # column counter
for i in range(1, plot_rows+1):
    for j in range(1, plot_cols+1):
        #print(str(i)+ ', ' + str(j))
        fig.add_trace(go.Scatter(x=df.iloc[:, 0], y=df.iloc[:, x],
                                 name=df.columns[x],
                                 mode='lines'),
                      row=i,
                      col=j)
        x = x+1
creeser
  • 363
  • 1
  • 4
  • 11
  • Is status in the data? If the amount of data is small, can it be presented in text? Please post that and the current output as well. – r-beginners Jan 08 '22 at 03:37
  • I think @vestland's answer [here](https://stackoverflow.com/questions/64760484/plotly-how-to-display-different-color-segments-on-a-line-chart-for-specified-th) will get you started on the right path. I'll work on integrating that solution into your specific question when I have the chance – Derek O Jan 08 '22 at 08:44

1 Answers1

2
  • taken approach of reshaping dataframe to be ready for plotly express
  • have worked out starting dataframe from description, a sample would be better
import pandas as pd
import plotly.express as px

df = pd.DataFrame(
    np.random.randint(1, 10, [100, 12]), columns=[f"c{i+1}" for i in range(12)]
).assign(status=np.repeat(np.random.randint(0, 2, 20), 5))

# restructure dataframe for px
# 1. preserve status in index
# 2. make columns another level of index
# 3. make index columns and make column names meaningful
dfp = (
    df.set_index("status", append=True)
    .stack()
    .reset_index()
    .rename(columns={"level_0": "x", "level_2": "facet", 0: "value"})
)

# make sure missing values are present as NaN
dfp = dfp.merge(
    pd.DataFrame(index=pd.MultiIndex.from_product(
        [dfp["x"].unique(), dfp["facet"].unique(), dfp["status"].unique()]
    )),
    left_on=["x", "facet", "status"],
    right_index=True,
    how="right"
)

# now it's a very simple plot
px.line(dfp, x="x", y="value", color="status", facet_col="facet", facet_col_wrap=4)


enter image description here

expected structure or df

  • 13 columns, last column indicating the status
c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 status
10 7 3 1 7 2 8 1 3 9 6 3 8 1
11 4 5 8 9 5 4 3 6 3 7 4 8 1
12 6 3 2 6 5 6 4 3 5 3 9 7 1
13 4 2 4 8 6 3 3 5 8 8 1 4 1
14 4 9 9 3 1 8 2 5 1 5 1 4 1
15 4 9 6 2 9 4 1 6 6 1 6 1 0
16 8 5 9 7 7 3 1 1 2 5 2 9 0
17 6 1 4 2 8 5 9 8 2 4 8 4 0
18 1 6 1 3 8 5 5 9 8 9 2 9 0
19 1 4 1 1 7 8 2 3 5 6 6 4 0
Rob Raymond
  • 29,118
  • 3
  • 14
  • 30
  • Wow!! It works. I don't fully understand your code at the moment, but I'll study it. Thanks Greatly! – creeser Jan 09 '22 at 18:39
  • the reshaping of dataframe you can look at each intermediate step. key is that **dfp** has a column for x,y, color and facet. This needs to include NaN where nothing is to be plotted for combination of mentioned columns – Rob Raymond Jan 09 '22 at 18:45
  • 1
    facet plotting, now I know....so much to learn... – creeser Jan 09 '22 at 18:54