Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Seaborn Matplotlib:获取绘图外的自定义图例_Python_Matplotlib_Seaborn - Fatal编程技术网

Python Seaborn Matplotlib:获取绘图外的自定义图例

Python Seaborn Matplotlib:获取绘图外的自定义图例,python,matplotlib,seaborn,Python,Matplotlib,Seaborn,我有一个函数,一次最多生成4个不同的绘图。图例需要与绘图分开保存 在我的代码中,我收集了所有标签,甚至为条形图中的峰值创建了一些标签 然后我分别显示它们,但由于某种原因,绘图结果是空白的 代码: 输出:基本上,除非您使用hue,seaborn绘图将不会呈现图例。因此,您的句柄和标签都是空的。此外,当mpatches部分填充句柄时,将标签保持为空且长度不相等,最终不会呈现任何图例 考虑按部分调整当前代码(底部链接中的完整代码)。然而,下面是演示。了解上述色调和mpatches标签问题,调整流程 数

我有一个函数,一次最多生成4个不同的绘图。图例需要与绘图分开保存

在我的代码中,我收集了所有标签,甚至为条形图中的峰值创建了一些标签

然后我分别显示它们,但由于某种原因,绘图结果是空白的

代码:


输出:

基本上,除非您使用
hue
seaborn
绘图将不会呈现图例。因此,您的
句柄和
标签都是空的。此外,当
mpatches
部分填充
句柄时,将
标签保持为空且长度不相等,最终不会呈现任何图例

考虑按部分调整当前代码(底部链接中的完整代码)。然而,下面是演示。了解上述
色调
mpatches
标签问题,调整流程

数据(为
色调
参数添加句点列)

条形图(调用
.get_legend().remove()
从原始图中删除)

线图(调用
.get_legend().remove()
从原始图中删除)

Mpatches(为每个手柄添加标签)


图例绘图(颜色/调色板需要调整)

条形图和线形图(颜色/调色板需要调整)

很好,您提供了一个完整的可运行示例。你能把代码简化一点吗?@np8我已经简化了代码。你使用的是哪个版本的seaborn和matplotlib?我为
hue
参数得到了一个ValueError。没关系!我的错误。这个很好用,谢谢!是否有更新值句柄的方法?示例在获得
temp\u handles
变量后,如何更新以显示“当前温度”而不是“当前”?只需将数据框中的
period
列指定为“当前温度”而不是“当前”。顺便说一句,使用
hue
,您可以将两个结构类似的数据帧(
pd.concat([current\u data\u frame,history\u data\u frame])
组合成一个
条形图,使用
dodge=False
参数和单个
lineplot
调用。根据需要调整调色板。如果我要更新period=“Current Temperature”的值,则条形图也会显示温度。条形图需要显示
当前功率
,而直线图显示
当前温度
degree = ' \u2109 '



def generate_graph_image():
    filename = 'test_bar.png'
    legend_file_name = 'legend.png'
    bar = True

    unit = 'Kw'
    time = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

    current_temperatures = [35, 45, 55, 65, 75, 85, 95, 100, 85, 65, 45, 35]
    # list is not always provided
    historic_temperatures = [35, 85,  35, 45, 55, 65, 75, 95, 100, 85, 65, 45,]

    current_readings = [.99, .75, .55, .10, .35, .05, .05, .08, .20, .55, .60, .85]
    # list is not always provided
    historic_readings = [.50, .05, .05, .08, .20,  .75, .55, .10, .35,.45, .65, .49, ]

    swap = True if sum(historic_readings) > sum(current_readings) else False

    time_label = 'Month'

    temp_label = f'Temperatures {degree}'
   
    current_data = {time_label: time, unit: current_readings, temp_label: current_temperatures}
    historic_data = {time_label: time, unit: historic_readings, temp_label: historic_temperatures}

    current_data_frame = pd.DataFrame(current_data)
    historic_data_frame = pd.DataFrame(historic_data)

    fig, current_ax = plt.subplots(figsize=(10, 6))
    current_color = 'blue'
    current_palette = "Reds"
    historic_color = 'black'
    historic_palette = "Blues_r"

    historic_ax = current_ax.twinx()
    historic_ax.axes.xaxis.set_visible(False)
    historic_ax.axes.yaxis.set_visible(False)
    historic_ax.axes.set_ylim(current_ax.axes.get_ylim())

    current_ax.set_xlabel('Time', fontsize=16)
    current_ax.set_ylabel(unit, fontsize=16, )

    current_peak = max(current_readings)
    current_peak_index = current_readings.index(current_peak)

    historic_peak = max(historic_readings)
    historic_peak_index = historic_readings.index(historic_peak)

    current_ax = sns.barplot(ax=current_ax, x=time_label, y=unit, data=current_data_frame, palette=current_palette, color=current_color, )
    current_ax.patches[current_peak_index].set_color('red')
    current_ax.patches[historic_peak_index].set_alpha(0.3)

    historic_ax = sns.barplot(ax=historic_ax, x=time_label, y=unit, data=historic_data_frame, palette=historic_palette,   color=historic_color, alpha=.7)
    historic_ax.patches[historic_peak_index].set_color('black')

    temperature_ax = current_ax.twinx()
    current_color = 'green'
    historic_color = 'orange'

    temperature_ax.set_ylabel(f'Temperature {degree}', fontsize=16,)
    temperature_ax = sns.lineplot(x=time_label, y=temp_label, data=current_data_frame, sort=False, color=current_color)
    temperature_ax.tick_params(axis='y', color=current_color
    temperature_ax = sns.lineplot(x=time_label, y=temp_label, data=historic_data_frame, sort=False, color=historic_color)
    temperature_ax.tick_params(axis='y', color=historic_color)

    plt.style.use('seaborn-poster')
    plt.style.use('ggplot')

    plt.savefig(fname=filename, dpi=200)

    figsize = (2.3, 2.3)
    fig_leg = plt.figure(figsize=figsize)
    fig_leg.set_size_inches(2.3, 2.3, forward=True)
    ax_leg = fig_leg.add_subplot(111)

    current_peak_reading_label = mpatches.Patch(color='red', label=f'Current Peak ({unit})')
    current_reading_label = mpatches.Patch(color='purple', label=f'Current {unit}')
    historic_peak_reading_label = mpatches.Patch(color='pink', label=f'Historic Peak ({unit})')
    historic_reading_label = mpatches.Patch(color='yellow', label=f'Historic {unit}')

    handles, labels = current_ax.get_legend_handles_labels()
    handles += [current_reading_label, current_peak_reading_label, historic_reading_label, historic_peak_reading_label]

    historic_handles, historic_labels = historic_ax.get_legend_handles_labels()
    handles += historic_handles
    labels += historic_labels
    temp_handles, temp_labels = temperature_ax.get_legend_handles_labels()
    handles += temp_handles
    labels += temp_labels
    ax_leg.legend(handles, labels, loc='center', frameon=False)
    # hide the axes frame and the x/y labels
    ax_leg.axis('off')
    fig_leg.savefig(legend_file_name, dpi=200, bbox_inches='tight')

    plt.show()
current_data_frame = pd.DataFrame(current_data).assign(period='current')
#    Month    Kw  Temperatures  ℉   period
# 0    Jan  0.99                35  current
# 1    Feb  0.75                45  current
# 2    Mar  0.55                55  current
# 3    Apr  0.10                65  current
# 4    May  0.35                75  current
# 5   June  0.05                85  current
# 6   July  0.05                95  current
# 7    Aug  0.08               100  current
# 8    Sep  0.20                85  current
# 9    Oct  0.55                65  current
# 10   Nov  0.60                45  current
# 11   Dec  0.85                35  current

historic_data_frame = pd.DataFrame(historic_data).assign(period='historic')
#    Month    Kw  Temperatures  ℉    period
# 0    Jan  0.50                35  historic
# 1    Feb  0.05                85  historic
# 2    Mar  0.05                35  historic
# 3    Apr  0.08                45  historic
# 4    May  0.20                55  historic
# 5   June  0.75                65  historic
# 6   July  0.55                75  historic
# 7    Aug  0.10                95  historic
# 8    Sep  0.35               100  historic
# 9    Oct  0.45                85  historic
# 10   Nov  0.65                65  historic
# 11   Dec  0.49                45  historic
current_ax = sns.barplot(ax=current_ax, x=time_label, y=unit, hue='period', data=current_data_frame, palette=current_palette, color=current_color, )
current_ax.patches[current_peak_index].set_color('red')
current_ax.patches[historic_peak_index].set_alpha(0.3)
current_ax.get_legend().remove()

historic_ax = sns.barplot(ax=historic_ax, x=time_label, y=unit, hue='period', data=historic_data_frame, palette=historic_palette, color=historic_color, alpha=.7)
historic_ax.patches[historic_peak_index].set_color('black')
historic_ax.get_legend().remove()
temperature_ax.set_ylabel(f'Temperature {degree}', fontsize=16,)

temperature_ax = sns.lineplot(x=time_label, y=temp_label, hue='period', data=current_data_frame, sort=False, palette=['g'])
temperature_ax.tick_params(axis='y', color=current_color)
temperature_ax.get_legend().remove()

temperature_ax = sns.lineplot(x=time_label, y=temp_label, hue='period', data=historic_data_frame, sort=False, palette=['orange'])
temperature_ax.get_legend().remove()
temperature_ax.tick_params(axis='y', color=historic_color)
#... same mpatches code ...

handles, labels = current_ax.get_legend_handles_labels()

# ADD LABEL TO CORRESPOND TO HANDLE
labels += ['current_reading_label', 'current_peak_reading_label', 'historic_reading_label', 'historic_peak_reading_label']
handles += [current_reading_label, current_peak_reading_label, historic_reading_label, historic_peak_reading_label]

historic_handles, historic_labels = historic_ax.get_legend_handles_labels()
handles += historic_handles
labels += historic_labels

temp_handles, temp_labels = temperature_ax.get_legend_handles_labels()
handles += [temp_handles[1]] + [temp_handles[3]]   # SKIP 1ST AND 3RD ITEMS (LEGEND TITLE, 'period')
labels += [temp_labels[1]] + [temp_labels[3]]      # SKIP 1ST AND 3RD ITEMS (LEGEND TITLE, 'period')