1

I use a for-loop to generate multiple images with fig.write_image in plotly. However, this gets very messy when there are many images. Is there a way to create a new folder and save these images in that folder when writing these images, so that all images will be stored in the same place rather than everywhere?

The code I used looks like below:

def draw(summary_df, data_df):

    for i, row in summary_df.iterrows():

        sub_df = data_df[(data_df.id== row.id) & (data_df.Timestamp >= row.start_time- datetime.timedelta(minutes=1)) & (data_df.Timestamp <= row.end_time +datetime.timedelta(minutes=1))]

        fig = go.Figure()
        
        fig.add_trace(go.Scatter(x=sub_df.Timestamp, y=sub_df.Data,
                            mode='lines+markers+text',
                            text = sub_df.Data,
                            textposition="top center",
                            textfont=dict(
                                family="arial",
                                size=10,
                                color="#6570f9") ))

        fig.update_layout(
        title=f'{i}. {row.id}, {row.Timestamp}', 
        xaxis_title="Timestamp",
        yaxis_title="Measurement",
        legend_title="Data",
        font=dict(
            size=11
        )
    )


        fig.write_image(f"{row.id}-{row.Timestamp.strftime('%Y-%m-%d_%H_%M_%S')}.png")
        fig.show()

1
  • 1
    You can use os.makedirs(directory) to create new folders. Which is your criteria to create a new folder and save images there? Commented May 17, 2022 at 3:00

2 Answers 2

1

First create a directory

image_path = "path/to/image"
if not os.path.exists("images"):
    os.mkdir(image_path)

Then import images to said directory inside your for loop:

from PIL import Image
import os


fig.write_image(f"{image_path}/{row.id}-{row.Timestamp.strftime('%Y-%m-%d_%H_%M_%S')}.png")
Sign up to request clarification or add additional context in comments.

Comments

1
  • pathlib is the way to go.
  • Simple case of using object based approach to file system. In this case it will put results into sub-directory of current working directory.
    out_dir = Path.cwd().joinpath("out")
    if not out_dir.exists():
        out_dir.mkdir()
  • the call to write your png
        fig.write_image(
            out_dir.joinpath(
                f"{row.id}-{row.Timestamp.strftime('%Y-%m-%d_%H_%M_%S')}.png"
            )

full code

  • have included some code to generate sample data frames
import pandas as pd
import numpy as np
import plotly.graph_objects as go
import datetime
from pathlib import Path


def draw(summary_df, data_df):
    out_dir = Path.cwd().joinpath("out")
    if not out_dir.exists():
        out_dir.mkdir()

    for i, row in summary_df.iterrows():

        sub_df = data_df[
            (data_df.id == row.id)
            & (data_df.Timestamp >= row.start_time - datetime.timedelta(minutes=1))
            & (data_df.Timestamp <= row.end_time + datetime.timedelta(minutes=1))
        ]

        fig = go.Figure()

        fig.add_trace(
            go.Scatter(
                x=sub_df.Timestamp,
                y=sub_df.Data,
                mode="lines+markers+text",
                text=sub_df.Data,
                textposition="top center",
                textfont=dict(family="arial", size=10, color="#6570f9"),
            )
        )

        fig.update_layout(
            title=f"{i}. {row.id}, {row.Timestamp}",
            xaxis_title="Timestamp",
            yaxis_title="Measurement",
            legend_title="Data",
            font=dict(size=11),
        )

        fig.write_image(
            out_dir.joinpath(
                f"{row.id}-{row.Timestamp.strftime('%Y-%m-%d_%H_%M_%S')}.png"
            )
        )
        fig.show()


# generate some sample data..
summary_df = (
    pd.DataFrame(
        index=pd.MultiIndex.from_product(
            [
                range(3),
                pd.date_range("1-may-2022", periods=3),
                pd.date_range("15-may-2022", periods=3),
            ],
            names=["id", "start_time", "end_time"],
        )
    )
    .reset_index()
    .assign(Timestamp=lambda d: pd.date_range("today", freq="5Min", periods=len(d)))
)

data_df = pd.concat(
    [
        pd.DataFrame(
            {"Timestamp": pd.date_range(r.start_time, r.end_time, freq="30H")}
        ).assign(id=r.id, Data=lambda d: np.random.randint(3, 10, len(d)))
        for i, r in summary_df.iterrows()
    ]
).sort_values(["id", "Timestamp", "Data"])

summary_df = summary_df.sample(4)

draw(summary_df, data_df)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.