2

目前我正在尝试绘制一个图表,显示一些正在运行的设备的排名,几天内排名从 1 到 300(1 是最好的,300 是最差的)(df 列)。我正在尝试做的是与此类似的图表:

在此处输入图像描述

我得到的是: 在此处输入图像描述

我想让线条在第一张图上倾斜而不是垂直,但我不知道如何。我在这里找到了关于这个问题的第一个图表的基础,并从那里开始编写代码,这就是我最终得到的:

import matplotlib.pyplot as plt
import matplotlib.ticker as plticker
import numpy as np

def energy_rank(data, marker_width=.5, color='blue'):
    y_data = np.repeat(data, 2)
    x_data = np.empty_like(y_data)
    x_data[0::2] = np.arange(1, len(data)+1) - (marker_width/2)
    x_data[1::2] = np.arange(1, len(data)+1) + (marker_width/2)
    
    lines = []
    lines.append(plt.Line2D(x_data, y_data, lw=0.8, linestyle='dashed', color=color,alpha=1,marker='.'))
    for x in range(0,len(data)*2, 2):
        lines.append(plt.Line2D(x_data[x:x+2], y_data[x:x+2], lw=2, linestyle='solid', color=color))
    return lines

head = 8
dfPlot = vazio.sort_values(dia, ascending = True).head(head)
data = dfPlot.to_numpy()

colorsHEX=('#FE5815','#001A70','#2F5C22','#B01338','#00030D','#2DE1FC','#2E020C','#B81D8C')

artists = []
for row, color in zip(data, colorsHEX):
    artists.extend(energy_rank(row, color=color))


eixoXDatas = pd.to_datetime(list(vazio.columns),format='%d/%m/%y').strftime('%d/%b')    

fig, ax = plt.subplots()
plt.xticks(np.arange(len(vazio.columns)),
           eixoXDatas,
           rotation = 35,
           fontsize = 14)
plt.yticks(fontsize = 14)

plt.xlabel('Dias', fontsize=18)
plt.ylabel('Ranking', fontsize=18)

fig = plt.gcf()
fig.set_size_inches(16, 8)

for artist in artists:
    ax.add_artist(artist)
ax.set_ybound([0,15])
ax.set_ylim(ax.get_ylim()[::-1])
ax.set_xbound([-0.1,float(len(vazio.columns))+2.5])
plt.yticks(np.arange(1,16,step=1))
ax.grid(axis='y',alpha=0.5)

lastDay = vazio.sort_values(vazio.iloc[:,-1:].columns.values[0], ascending = True).iloc[:,-1:]
lastDay = lastDay.head(head)

for inverter, pos in lastDay.iterrows():
    ax.annotate(inverter, xy =(plt.gca().get_xlim()[1]-2.4, pos), color=colorsHEX[int(pos)-1])

我尝试实现energy_rank功能,删除 +/- 部分,x_data但我只能得到带有点的斜线而不是水平线。任何人都可以帮助我如何保持水平线而不是垂直虚线,如上例所示实施斜线?

我想这是垂直的,因为点在 x 刻度上会发生变化。如果您观察第一张图像,水平条集中在每个 x 刻度上,因此线条“有一些空间”可以倾斜。

vazio数据帧如下(包含每个设备的等级):

    Equipment         21-03-27  21-03-28    21-03-29    21-03-30    21-03-31    21-04-01    21-04-02 
P01-INV-1-1              1         1           1           1           1           2           2
P01-INV-1-2              2         2           4           4           5           1           1
P01-INV-1-3              4         4           3           5           6           10          10
4

1 回答 1

1

这是您energy_rank创建水平线段及其连接的函数的改编。画线部分的灵感来自本教程示例。可以选择填充线条下方的区域。

import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
import numpy as np

def energy_rank(data, marker_width=.5, color='blue', ax=None, fill=False):
    ax = ax or plt.gca()
    y = data
    x = np.arange(1, len(data) + 1)

    segments1 = np.array([x - marker_width / 2, y, x + marker_width / 2, y]).T.reshape(-1, 2, 2)
    lc1 = LineCollection(segments1, color=color)
    lc1.set_linewidth(2)
    lc1.set_linestyle('-')
    lines_hor = ax.add_collection(lc1)

    segments2 = np.array([x[:-1] + marker_width / 2, y[:-1], x[1:] - marker_width / 2, y[1:]]).T.reshape(-1, 2, 2)
    lc2 = LineCollection(segments2, color=color)
    lc2.set_linewidth(0.5)
    lc2.set_linestyle('--')
    lines_connect = ax.add_collection(lc2)

    if fill:
        ax.fill_between(segments1.reshape(-1,2)[:,0], segments1.reshape(-1,2)[:,1],
                        color=color, alpha=0.05)
    return lines_hor, lines_connect

fig, ax = plt.subplots()

M, N = 5, 25
y = np.random.uniform(-2, 2, (M, N)).cumsum(axis=1)
y += np.random.uniform(0.5, 2, (M, 1)) - y.min(axis=1, keepdims=True)
colorsHEX = ('#FE5815', '#001A70', '#2F5C22', '#B01338', '#00030D')
for yi, color in zip(y, colorsHEX):
    energy_rank(yi, ax=ax, color=color)

ax.set_xlim(0, N + 1)
ax.set_ylim(0, y.max() + 1)
plt.show()

用虚线连接的水平线段

于 2021-04-13T22:41:21.623 回答