Мне очень нравятся цветы!!!
Тема цветов была выбрана благодаря личному интересу к флористике и эстетике природы. Мне было интересно взглянуть на них не только с эстетической, но и с аналитической стороны — выявить закономерности, скрытые в данных: какие климатические зоны наиболее богаты разнообразием цветов, какие из них чаще используются в парфюмерии, как связаны высота и продолжительность жизни растения. Этот проект позволил совместить любовь к природе с интересом к анализу данных.

Цветы сопровождают человека всегда: от букетов на первом свидании до торжественных церемоний. Мы привыкли видеть в них красоту, но за каждым цветком стоит своя история — где он родился, как долго живёт, используют ли его в парфюмерии или медицине.
В этом проекте я исследую датасет, содержащий информацию о 73 видах цветов. Здесь собраны данные о происхождении, высоте, продолжительности жизни, количестве лепестков и промышленном использовании растений.
С помощью четырёх типов визуализации — столбчатых и круговых диаграмм, точечных графиков и тепловых карт — я попытаюсь найти закономерности в мире флоры и ответить на вопросы: какие цветы доминируют в промышленности, где находится главный «цветочный» регион планеты и существует ли связь между количеством лепестков и высотой растения.
Для визуализации данных я планирую использовать следующие типы графиков: • Тепловая карта • Столбчатая диаграмма • Круговая диаграмма • Точечный график (scatter plots)
Визуальное оформление
Графики оформлены в природном и наглядном стиле, соответствующем тематике цветов.
Загрузка данных
Для работы я импортировала библиотеки: pandas для работы с данными, matplotlib.pyplot для построения графиков, и загрузила основной файл из датасета. Также, для тепловой карты, использовалась библиотека matplotlib.colors.
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns df = pd.read_csv( 'flowers.csv',
Круговая диаграмма
Была построена круговая диаграмма соотношения цветов, используемых как срезочные, и не используемых в этом качестве. Для построения круговой диаграммы необходимо было отфильтровать данные по столбцу cut flowers, после чего нужно было посчитать количество цветов со значением 1 (используются как срезочные) и 0 (не используются как срезочные).
На круговой диаграмме представлено соотношение цветов, которые используются как срезочные (cut flowers = 1), и тех, которые не применяются в этом качестве (cut flowers = 0). Для визуализации данных была использована пользовательская цветовая палитра и настроен стиль текста.
from io import StringIO
Загрузка данных в pandas
df = pd.read_csv(StringIO(data))
Просмотр данных
print("✅ Данные загружены!") print(f"\n📊 Размер данных: {df.shape[0]} строк, {df.shape[1]} столбцов") print(f"\n📋 Названия столбцов:") print(df.columns.tolist())
print("\n🔍 Первые 5 строк:") print(df.head())
print("\n📈 Информация о данных:") print(df.info())
Круговая диаграмма для cut flowers
cut_flowers_counts = df['cut flowers'].value_counts() cut_flowers_counts.index = cut_flowers_counts.index.map({1: 'Используются как срезочные', 0: 'Не используются как срезочные'})
Цветовая палитра
colors = ["
69BE28", "
FEC2C8"]Настройка стиля
plt.rcParams.update({ 'font.size': 14, 'font.weight': 'bold', 'text.color': 'black' })
Построение диаграммы
plt.figure(figsize=(7, 7)) plt.pie(cut_flowers_counts, labels=cut_flowers_counts.index, autopct='%1.1f%%', colors=colors, startangle=90, wedgeprops={'edgecolor': 'black', 'linewidth': 1}, textprops={'color': 'black'})
plt.title("Соотношение цветов, используемых как срезочные", fontsize=14, fontweight='bold') plt.axis('equal') plt.tight_layout() plt.show()
Статистика
print(f"\n📊 Статистика:") print(f"Всего цветов: {len(df)}") print(f"Срезочные цветы: {cut_flowers_counts['Используются как срезочные']} ({cut_flowers_counts['Используются как срезочные']/len(df)*100:.1f}%)") print(f"Не срезочные: {cut_flowers_counts['Не используются как срезочные']} ({cut_flowers_counts['Не используются как срезочные']/len(df)*100:.1f}%)")
Точечный график
Благодаря этому точечному графику мы увидели, как связаны продолжительность жизни цветов и их высота. А также различия в этих показателях между цветами разных оттенков.
После фильтрации цветов, которые используются в парфюмерии (perfumes = 1), от остальных видов, я приступила к построению графика. На нём каждая точка представляет отдельный цветок, а цвет точки соответствует его окрасу.
from io import StringIO
Загрузка данных
df = pd.read_csv(StringIO(data))
Фильтруем данные — оставляем только цветы, которые используются в парфюмерии (perfumes = 1)
df_perfume = df[df['perfumes'] == 1]
Проверяем, есть ли данные
if not df_perfume.empty:
# Преобразуем строковые диапазоны в числовые значения (берем среднее)
def convert_height(height_str):
if '-' in str(height_str):
low, high = height_str.split('-')
return (float(low) + float(high)) / 2
return float(height_str)
df_perfume['height (cm)_numeric'] = df_perfume['height (cm)'].apply(convert_height)
# Преобразуем longevity в числовые значения
def convert_longevity(longevity_str):
if '-' in str(longevity_str):
low, high = longevity_str.split('-')
return (float(low) + float(high)) / 2
return float(longevity_str)
df_perfume['longevity (years)_numeric'] = df_perfume['longevity (years)'].apply(convert_longevity)
# Цветовая палитра
colors = ["<h3>69BE28", "</h3>FEC2C8", "<h3>FFF6B3", "</h3>9F01D2", "#AEF0FF"]
# Создаем словарь цветов для разных оттенков
unique_colors = df_perfume['color'].unique()
color_map = {color: colors[i % len(colors)] for i, color in enumerate(unique_colors)}
# Строим точечный график с помощью matplotlib
plt.figure(figsize=(12, 8))
for color_type in unique_colors:
subset = df_perfume[df_perfume['color'] == color_type]
plt.scatter(subset['height (cm)_numeric'],
subset['longevity (years)_numeric'],
c=color_map[color_type],
label=color_type,
s=100,
alpha=0.8,
edgecolor='black')
Улучшаем внешний вид
plt.grid(True, linestyle='--', alpha=0.7)
plt.legend(title="Цвет", bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
# Отображаем график
plt.show()
# Выводим статистику
print(f"\n📊 Статистика:")
print(f"Всего цветов, используемых в парфюмерии: {len(df_perfume)}")
print(f"Средняя высота: {df_perfume['height (cm)_numeric'].mean():.1f} см")
print(f"Средняя продолжительность жизни: {df_perfume['longevity (years)_numeric'].mean():.1f} лет")
print(f"\n🌸 Цвета:")
print(df_perfume['color'].value_counts())
else: print("⚠️ В данных нет цветов, используемых в парфюмерии (perfumes = 1)")
Для понимания графика, я сделала подписи к осям Х и Y.
Заголовок и подписи
plt.title("Зависимость продолжительности жизни от высоты цветов, используемых в парфюмерии 🌸",
fontsize=16, fontweight='bold')
plt.xlabel("Высота (см)", fontsize=14)
plt.ylabel("Продолжительность жизни (годы)", fontsize=14)
Тепловая карта
Для построения тепловой карты я определила топ-5 климатических зон, в которых произрастает наибольшее количество цветов. Затем сгруппировала данные по климатическим зонам и признаку использования в парфюмерии, чтобы выявить, в каких климатических условиях цветы чаще используются для создания ароматов. На основе этих данных построила тепловую карту, где интенсивность цвета отображает количество цветов в каждой категории.
from io import StringIO
Загрузка данных
df = pd.read_csv(StringIO(data))
1. Выбираем топ-5 самых популярных климатических зон
top_5_climates = df['climate'].value_counts().head(5).index.tolist()
2. Фильтруем DataFrame по этим климатическим зонам
df_top = df[df['climate'].isin(top_5_climates)].copy()
3. Создаем столбец с текстовым обозначением использования в парфюмерии
df_top['perfumes_text'] = df_top['perfumes'].map({1: 'Используется в парфюмерии', 0: 'Не используется'})
4. Строим сводную таблицу: климат → использование в парфюмерии → количество цветов
pivot_df = df_top.groupby(['climate', 'perfumes_text']).size().unstack(fill_value=0)
5. Сортируем строки (климатические зоны) по популярности
pivot_df = pivot_df.loc[pivot_df.sum(axis=1).sort_values(ascending=False).index]
6. Создаем тепловую карту с помощью matplotlib (без seaborn)
fig, ax = plt.subplots(figsize=(10, 8))
Цветовая карта (от зеленого к розовому)
colors = ["
69BE28", "
FEC2C8", "FFF6B3", "
9F01D2", "#AEF0FF"]Создаем цветовую карту для тепловой карты
cmap = plt.cm.colors.ListedColormap(colors[:len(pivot_df.columns)])
Рисуем тепловую карту
im = ax.imshow(pivot_df.values, cmap=cmap, aspect='auto')
Настройка осей
ax.set_xticks(np.arange(len(pivot_df.columns))) ax.set_yticks(np.arange(len(pivot_df.index))) ax.set_xticklabels(pivot_df.columns, rotation=15, ha='right') ax.set_yticklabels(pivot_df.index)
Добавляем значения в ячейки
for i in range(len(pivot_df.index)): for j in range(len(pivot_df.columns)): text = ax.text(j, i, pivot_df.values[i, j], ha="center", va="center", color="black", fontweight='bold')
Настройка внешнего вида
ax.set_xlabel("Использование в парфюмерии", fontsize=12) ax.set_ylabel("Климатическая зона", fontsize=12) ax.set_title("Распределение использования в парфюмерии по климатическим зонам", fontsize=14, fontweight='bold')
Добавляем рамки между ячейками
for i in range(len(pivot_df.index) + 1): ax.axhline(i - 0.5, color='white', linewidth=2) for j in range(len(pivot_df.columns) + 1): ax.axvline(j - 0.5, color='white', linewidth=2)
plt.tight_layout() plt.show()
Выводим статистику
print("\n📊 Статистика:") print(f"Всего цветов в выборке: {len(df_top)}") print(f"\nТоп-5 климатических зон:") for i, climate in enumerate(top_5_climates, 1): count = df[df['climate'] == climate].shape[0] print(f"{i}. {climate}: {count} цветов")
print(f"\nРаспределение по климатическим зонам:") print(pivot_df)
Столбчатая диаграмма




