簡體   English   中英

plot序列數據,如何根據簇改變顏色

[英]How to plot sequential data, changing the color according to cluster

我有一個 dataframe,其中包含有關日期和它所屬的集群的信息(之前是根據每天收集的溫度完成的)。 我想按順序排列 plot 這個數據,就像一個堆積條形圖,根據分配的簇改變每個元素的顏色。 這是我的桌子(信息最多 100 天):

日期 命令 集群No2 不變
2020-08-07 1個 3.0 1個
2020-08-08 2個 0.0 1個
2020-08-09 3個 1.0 1個
2020-08-10 4個 3.0 1個
2020-08-11 5個 1.0 1個
2020-08-12 6個 1.0 1個
2020-08-13 7 3.0 1個
2020-08-14 8個 2.0 1個
2020-08-15 9 2.0 1個
2020-08-16 10 2.0 1個
2020-08-17 11 2.0 1個
2020-08-18 12 1.0 1個
2020-08-19 13 1.0 1個
2020-08-20 14 0.0 1個
2020-08-21 15 0.0 1個
2020-08-22 16 1.0 1個

Obs:我不能簡單地按集群對數據進行分組,因為 plot 應該是連續的。 我想寫一個代碼來按順序識別每個集群的元素數量,但隨后我將面臨同樣的繪圖問題。 有人知道如何解決這個問題嗎?

預期結果應該是這樣的(條形內的數字代表集群,x 軸以天為單位的時間和條形寬度按順序表示具有相同集群的觀察天數: 示例圖

您可以使用 x 軸的日期、y 軸的“常量”列和着色的集群 ID。

您可以使用彩色矩形列表創建自定義圖例。

import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
import pandas as pd
import numpy as np

N = 100
df = pd.DataFrame({'Date': pd.date_range('2020-08-07', periods=N, freq='D'),
                   'order': np.arange(1, N + 1),
                   'ClusterNo2': np.random.randint(0, 4, N).astype(float),
                   'constant': 1})
df['ClusterNo2'] = df['ClusterNo2'].astype(int)  # convert to integers

fig, ax = plt.subplots(figsize=(15, 3))

num_clusters = df['ClusterNo2'].max() + 1
colors = plt.cm.Set2.colors
ax.bar(x=range(len(df)), height=df['constant'], width=1, color=[colors[i] for i in df['ClusterNo2']], edgecolor='none')
ax.set_xticks(range(len(df)))
labels = ['' if i % 3 != 0 else day.strftime('%d\n%b %Y') if i == 0 or day.day <= 3 else day.strftime('%d')
          for i, day in enumerate(df['Date'])]
ax.set_xticklabels(labels)
ax.margins(x=0, y=0)
ax.yaxis.set_major_locator(MaxNLocator(integer=True))
legend_handles = [plt.Rectangle((0, 0), 0, 0, color=colors[i], label=f'{i}') for i in range(num_clusters)]
ax.legend(handles=legend_handles, title='Clusters', bbox_to_anchor=(1.01, 1.01), loc='upper left')
fig.tight_layout()
plt.show()

集群的條形圖

您可以只是 plot 一個普通的條形圖,其中 1 個條對應 1 天。 如果您將寬度也設置為 1,則看起來補丁是連續的。

在此處輸入圖像描述

import numpy as np
import matplotlib.pyplot as plt

from matplotlib.colors import BoundaryNorm

# simulate data
total_datapoints = 16
total_clusters = 4
order = np.arange(total_datapoints)
clusters = np.random.randint(0, total_clusters, size=total_datapoints)

# map clusters to colors
cmap = plt.cm.tab10
bounds = np.arange(total_clusters + 1)
norm = BoundaryNorm(bounds, cmap.N)
colors = [cmap(norm(cluster)) for cluster in clusters]

# plot
fig, ax = plt.subplots()
ax.bar(order, np.ones_like(order), width=1, color=colors, align='edge')

# xticks
change_points = np.where(np.diff(clusters) != 0)[0] + 1
change_points = np.unique([0] + change_points.tolist() + [total_datapoints])
ax.set_xticks(change_points)

# annotate clusters
for ii, dx in enumerate(np.diff(change_points)):
    xx = change_points[ii] + dx/2
    ax.text(xx, 0.5, str(clusters[int(xx)]), ha='center', va='center')

ax.set_xlabel('Time (days)')
plt.show()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM