У меня есть следующая диаграмма:
Вот код 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 представляет собой блок. Последние два блока зеленые. Однако между этими двумя есть небольшая линия, которую я хотел бы удалить, чтобы она представляла собой сплошную зеленую полосу.
Это связано с тем, что время начала второго блока следует не сразу.
Итак, чтобы устранить пробел, вы можете использовать
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), но у меня это не работает.
Можете ли вы поделиться набором данных, который вас утомляет?
То же, что и в репозитории 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': ['зеленый', ' зеленый','зеленый'] }
он показывает другой сегмент в plotly.graph_objects
, вы можете использовать альтернативные варианты, например matplotlib.pyplot
plotly.graph_objects, я здесь, даже если использовать line=dict(width=0, color='rgba(0,0,0,0)')
вот так, он все равно будет отображаться по умолчанию. Лучший способ удовлетворить ваши требования — найти альтернативную библиотеку графиков.
Я попробовал это с данными, упомянутыми выше, ответом,
Итак, предполагая, что ваши данные выглядят следующим образом:
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
и я получаю следующий результат:
Да, спасибо, у меня тоже работает. Мне было интересно, можно ли добавить небольшой параметр, чтобы эта маленькая область исчезла. Спасибо.
Рад, что это помогло. Приятного кодирования!
Не могли бы вы поделиться данными, которые вы используете?