Seaborn水平条形图

时间:2017-05-02 15:15:00

标签: python-2.7 matplotlib bar-chart seaborn

默认的Seaborn条形图几乎适用于我,尽管有一些细节。如下所示:

Seaborn Horizontal Bar Plot

请查看每个栏旁边和右侧的“文字”注释。我想改进一些事项:

  1. 由于某种原因,最后一个栏不显示注释。我不知道如何解决这个问题。

  2. 条形边缘与顶部和底部X轴之间没有空隙。我想在那里留一些空间。

  3. 无论如何,是否可以增加条的宽度?

  4. 我还想增加“最高”条和右Y轴之间的距离,因为我计划添加文字而不仅仅是与X轴值对应的厚度数。如果你看一下与HRA的Red0类别相对应的栏,它会像105.65(42.54%)。这将明显地将其推到右Y轴的边缘。有没有办法在其峰值和最大X轴值之间增加一些距离?因此,例如,如果我可以将其设置为条形的最大高度(易于计算)加上一定量。

  5. 如果我可以处理这些细节,它会让它变得完美!

    以下是我的代码片段与上述问题相关:

    sns.set_style('whitegrid')
    sns.set(font_scale=0.8)
    thickness = []
    for hra_color in df_hra_colors['hra']:
        thickness.append(grouped.get_group(hra_color).count()['hra'] * mult)
    df_hra_colors['thickness'] = thickness
    ax = sns.barplot(x='thickness', y='hra', data=df_hra_colors,
                     palette=df_hra_colors['hex'].tolist())
    ax.set_xlabel("Thickness")
    ax.set_ylabel("HRA")
    ax.set_title("What an Awesome Plot!")
    for p in ax.patches:
        ax.annotate("%.2f" % p.get_width(), (p.get_x() + p.get_width(), p.get_y() + 1.2),
                    xytext=(5, 10), textcoords='offset points')
    plt.show()
    

    以下是所要求的最小,完整的可验证示例:

    """ Minimal program for demonstration """
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    def main():
        sns.set_style('whitegrid')
        sns.set(font_scale=0.8)
        # plt.rcParams['figure.figsize'] = (10,10)
        df_hra_colors = pd.DataFrame({
            'hra': ['red', 'green', 'blue'],
            'hex': ['#cc0000', '#40ff00', '#0000ff']
        })
        thickness = [1, 2, 3]
        thick_sum = sum(thickness)
        df_hra_colors['thickness'] = thickness
        ax = sns.barplot(x='thickness', y='hra', data=df_hra_colors,
                         palette=df_hra_colors['hex'].tolist())
        plt.xlim(0, max(thickness) + 30)
        ax.set_xlabel("Thickness")
        ax.set_ylabel("HRA")
        ax.set_title("What an Awesome Plot!")
        for i, p in enumerate(ax.patches):
            ax.annotate("%.2f (%.2f)%%" % (p.get_width(), thickness[i] / thick_sum * 100.0),
                        (p.get_x() + p.get_width(), p.get_y() + 1),
                        xytext=(5, 10), textcoords='offset points')
        plt.show()
    
    if __name__ == "__main__":
        main()
    

    这就是它的样子: enter image description here

    然后我将更改为1的行更改为p.get_y()以添加0.5,如下所示:

    for i, p in enumerate(ax.patches):
        ax.annotate("%.2f (%.2f)%%" % (p.get_width(), thickness[i] / thick_sum * 100.0),
                    (p.get_x() + p.get_width(), p.get_y() + 0.5),
                    xytext=(5, 10), textcoords='offset points')
    

    enter image description here 这就是我得到的:

    因此,由于偏移,隐藏了带注释的文本。使用这些知识,我可以调整我的原始脚本,以在最后一个栏中显示带注释的文本。但这导致了另外一个问题。如果您事先不知道条形数,如何调整代码以保持一致?

    你的答案2工作正常。谢谢。

    由于我使用的是sns.barplot,因此3号对我不起作用。 Python不喜欢调用barplot中的width参数。

    4号工作正常。谢谢。

    感谢您对我的问题的帮助。

1 个答案:

答案 0 :(得分:0)

  1. 关于第一点,我们需要一个minimal, complete, verifiable example

  2. 为了在边缘条和轴之间留出空间,可以调整轴的极限。 import { Component } from '@angular/core'; import { Router } from '@angular/router'; import { EventCreate } from './eventCreate'; @Component({ selector: 'add-Event', templateUrl: './event-add.component.html', }) export class EventAddComponent { title: string; description: string; locationId: number; locationDetails: string; categoryId: number; isRegistrationRequired: boolean; eventDate: Date; startDateTime: Date; endDateTime: Date; maximumRegistrants: number; newEvent: EventCreate; constructor(private router: Router) { } createNewEvent() { console.log('new Event Created'); this.newEvent = new EventCreate( this.title, this.description, this.locationId, this.locationDetails, this.categoryId, this.isRegistrationRequired, this.eventDate, this.startDateTime, this.endDateTime, this.maximumRegistrants ); console.log(this.newEvent); //call service //call route to go to Home page this.router.navigate(['/home']); } cancel() { this.router.navigate(['/home']); } } export class EventCreate { constructor( public title: string, public description: string, public locationId: number, public locationDetails: string, public categoryId: number, public isRegistrationRequired: boolean, public eventDate: Date, public startDateTime: Date, public endDateTime: Date, public maximumRegistrants: number, ) { } } <form> <div class="form-group"> <label>Start Time:</label> <input type="time" name="startDateTime" [(ngModel)]="startDateTime"> </div> <div class="form-group"> <label>End Time:</label> <input type="time" name="endDateTime" [(ngModel)]="endDateTime"> </div> </form> ,其中ax.set_ylim(-1,N)是条数。

  3. 可以使用N width参数设置条形的宽度。 plt.bar;或者,对于水平条,使用plt.bar(..., width=1)参数。 seaborn条形图不允许设置宽度或高度。

  4. 与{2}相同,只有height,其中ax.set_xlim(0,barmax*1.4)是条的最大长度。