Удалить пробелы в диаграмме

У меня есть следующая диаграмма:

Вот код Python, который генерирует диаграмму:

def createBarChart(df):
    # Convert the columns ‘start’ and ‘end’ into datetime objects
    df['start'] = pd.to_datetime(df['start'])
    df['ende'] = pd.to_datetime(df['ende'])

    # Create Diagramm
    fig = go.Figure()

    for i, row in df.iterrows():
        fig.add_trace(go.Scatter(
            x=[row['start'], row['ende'], row['ende'], row['start']],
            y=[1, 1, 0, 0],
            fill='toself',
            fillcolor=row['color'],
            mode='none',  
            showlegend=False,

        ))

    # Formatting the x-axis
    tickvals = pd.date_range(start=df['start'].min(), end=df['ende'].max(), freq='3H')
    ticktext = []
    previous_day = None

    for d in tickvals:
        if previous_day is None or d.day != previous_day:
            ticktext.append(f"<b>{d.strftime('%d.%m')}</b>")
        else:
            ticktext.append(d.strftime('%H:%M'))
        previous_day = d.day

    fig.update_layout(
        yaxis=dict(showticklabels=False),
        xaxis=dict(
            tickformat='%H:%M',
            tickvals=tickvals,
            ticktext=ticktext
        ),
        margin=dict(l=20, r=20, t=10, b=20),
        height=200,

    )

    return fig

Теперь мы подошли к проблеме. Чтобы отобразить диаграмму, я читаю файл CSV. Каждая строка в файле CSV представляет собой блок. Последние два блока зеленые. Однако между этими двумя есть небольшая линия, которую я хотел бы удалить, чтобы она представляла собой сплошную зеленую полосу.

Не могли бы вы поделиться данными, которые вы используете?

Nijat Mursali 27.08.2024 10:56
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это связано с тем, что время начала второго блока следует не сразу.

Итак, чтобы устранить пробел, вы можете использовать

    for i in range(len(df) - 1):
        if df.loc[i, 'color'] == df.loc[i + 1, 'color']:
            df.loc[i, 'ende'] = df.loc[i + 1, 'start']

это обеспечит соответствие времени окончания текущей строки времени начала следующей строки.

Полный код: Ссылка

Если это plotly.graph_objects поведение по умолчанию, то

Вы можете перейти в альтернативную библиотеку, например matplotlib.pyplot, и обновить код в соответствии с ней.

Альтернативный вариант: Полный код: Ссылка

Я только что попробовал ваш код. В моем CSV-файле периоды времени также следуют друг за другом. Например: начало 09:50 окончание 10:45; начало 10:45 окончание 18:45; начало 18:45 окончание 10:00. Когда я запускаю ваш код, я все равно получаю тире. Думаю, дело в ширине. Я уже пробовал: line=dict(width=None), но у меня это не работает.

ranqnova 27.08.2024 10:07

Можете ли вы поделиться набором данных, который вас утомляет?

Sasanka Weerakoon 27.08.2024 10:19

То же, что и в репозитории GitHub: data = { 'start': ['2024-08-27 09:50', '2024-08-27 10:45', '2024-08-27 18:45'] , 'ende': ['2024-08-27 10:45', '2024-08-27 18:45', '2024-08-27 20:00'], 'color': ['зеленый', ' зеленый','зеленый'] }

ranqnova 27.08.2024 10:24

он показывает другой сегмент в plotly.graph_objects, вы можете использовать альтернативные варианты, например matplotlib.pyplot

Sasanka Weerakoon 27.08.2024 10:31

plotly.graph_objects, я здесь, даже если использовать line=dict(width=0, color='rgba(0,0,0,0)') вот так, он все равно будет отображаться по умолчанию. Лучший способ удовлетворить ваши требования — найти альтернативную библиотеку графиков.

Sasanka Weerakoon 27.08.2024 10:34
Ответ принят как подходящий

Я попробовал это с данными, упомянутыми выше, ответом,

Итак, предполагая, что ваши данные выглядят следующим образом:

data = {
    'start': ['2024-08-27 08:00', '2024-08-27 09:00', '2024-08-27 10:00', '2024-08-27 11:00', '2024-08-27 12:00'],
    'ende':  ['2024-08-27 09:00', '2024-08-27 10:00', '2024-08-27 11:00', '2024-08-27 12:00', '2024-08-27 13:00'],
    'color': ['green', 'green','green', 'green', 'green']
}

и измененная функция будет:

def createBarChart(df):
    # Convert the columns 'start' and 'end' into datetime objects
    df['start'] = pd.to_datetime(df['start'])
    df['ende'] = pd.to_datetime(df['ende'])

    # Sorting the data
    df = df.sort_values(by='start').reset_index(drop=True)

    # Merge consecutive blocks with the same color
    merged_df = []
    current_start = df.loc[0, 'start']
    current_end = df.loc[0, 'ende']
    current_color = df.loc[0, 'color']

    for i in range(1, len(df)):
        if df.loc[i, 'color'] == current_color and df.loc[i, 'start'] == current_end:
            current_end = df.loc[i, 'ende']
        else:
            merged_df.append({'start': current_start, 'ende': current_end, 'color': current_color})
            current_start = df.loc[i, 'start']
            current_end = df.loc[i, 'ende']
            current_color = df.loc[i, 'color']

    # Don't forget to append the last block
    merged_df.append({'start': current_start, 'ende': current_end, 'color': current_color})

    # Convert merged_df to a DataFrame
    merged_df = pd.DataFrame(merged_df)

    # Create a figure diagram
    fig = go.Figure()

    for i, row in merged_df.iterrows():
        fig.add_trace(go.Scatter(
            x=[row['start'], row['ende'], row['ende'], row['start']],
            y=[1, 1, 0, 0],
            fill='toself',
            fillcolor=row['color'],
            mode='none',  
            showlegend=False,
        ))

    # Formatting the x-axis
    tickvals = pd.date_range(start=merged_df['start'].min(), end=merged_df['ende'].max(), freq='3H')
    ticktext = []
    previous_day = None

    for d in tickvals:
        if previous_day is None or d.day != previous_day:
            ticktext.append(f"<b>{d.strftime('%d.%m')}</b>")
        else:
            ticktext.append(d.strftime('%H:%M'))
        previous_day = d.day

    fig.update_layout(
        yaxis=dict(showticklabels=False),
        xaxis=dict(
            tickformat='%H:%M',
            tickvals=tickvals,
            ticktext=ticktext
        ),
        margin=dict(l=20, r=20, t=10, b=20),
        height=200,
    )

    return fig

и я получаю следующий результат:

Да, спасибо, у меня тоже работает. Мне было интересно, можно ли добавить небольшой параметр, чтобы эта маленькая область исчезла. Спасибо.

ranqnova 27.08.2024 11:39

Рад, что это помогло. Приятного кодирования!

Nijat Mursali 27.08.2024 11:46

Другие вопросы по теме