【问题标题】:Move location of tick marks in Seaborn lineplot在 Seaborn 线图中移动刻度线的位置
【发布时间】:2020-06-15 03:18:00
【问题描述】:

我使用 seaborn 包做了一个情节。这是代码:

ax = sns.pointplot(x='latency_condition', y='flow', color=colors[0], ci=95, data=df_new,
                   scale=.5, linestyles='dotted', errwidth=2, capsize=.3)
ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
ax.set_xlabel("E(latency)", fontweight='bold')
ax.set_ylabel("Flow score", fontweight='bold')
ax.set_yticklabels(['min','','','neutral','','','max'])
ax.set(ylim = (10,70))
plt.axhline(y=40, color=colors[3], linestyle='--', linewidth=1)
plt.savefig("fig4_flow.pdf", bbox_inches='tight')
plt.show()

这一切都很好。现在,我在区间级别的 x 轴上有分类级别。它们代表延迟值,不幸的是,“丑陋”:[162、245、328、412、495、578]

如果我的 x 轴每 100 有刻度线,我会更喜欢它,例如,以提高可读性。但是,seaborn 将它们(正确地)视为分类级别,所以我不能只更改 x 轴。

我想做的是:

  • 删除当前的 xticks 并用新的 xticks 替换它们(例如每 100 个)
  • 这样做的方式是新的 xticks 尊重坐标系(因为旧的 xticks 也是均匀分布的,代表底层的连续体)。

【问题讨论】:

    标签: python python-3.x matplotlib seaborn


    【解决方案1】:

    一个想法是使用辅助x轴并设置与点-0.5和5.5对应的限制:

    import matplotlib.pyplot as plt
    import seaborn as sns
    import pandas as pd
    import numpy as np
    
    # create some random data
    N = 100
    a = [162, 245, 328, 412, 495, 578]
    x = np.random.choice(a, N)
    y = np.random.normal(65 - x / 20, 10, N)
    df_new = pd.DataFrame({'latency_condition':x, 'flow': y})
    
    fig, ax1 = plt.subplots()
    
    ax2 = ax1.twiny()
    sns.pointplot(ax=ax2, x='latency_condition', y='flow', color='dodgerblue', ci=95, data=df_new,
                  scale=.5, linestyles='dotted', errwidth=2, capsize=.3)
    
    # ax2.tick_params(axis='x', rotation=45)
    # ax1.tick_params(axis='x', rotation=45)
    ax2.set_xlabel("")
    ax1.set_xlabel("E(latency)", fontweight='bold')
    ax1.set_xlim(1.5*a[0] - 0.5*a[1], -0.5*a[-2] + 1.5*a[-1])
    ax1.set_ylabel("Flow score", fontweight='bold')
    ax1.set_yticklabels(['min','','','neutral','','','max'])
    ax1.set(ylim = (10,70))
    
    ax1.axhline(y=40, color='crimson', linestyle='--', linewidth=1)
    #plt.savefig("fig4_flow.pdf", bbox_inches='tight')
    plt.tight_layout()
    plt.show()
    

    【讨论】:

    • 哇,这可能是我与合著者讨论的解决方案。谢谢!
    【解决方案2】:

    我不相信这不是一个坏主意。 pointplot() 旨在用于分类数据,而将其用于连续数据(即使您的 x 轴只取几个离散值)也是自找麻烦。

    无论如何,在 seaborn 的 pointplot() 中,分类变量的水平绘制在 x 轴坐标 0,1,...,N-1 处。由于您知道每个点的延迟值,因此只需进行线性插值即可找到所需的 x 值,以获得您选择的整数:

    ticks = [162, 245, 328, 412, 495, 578]
    new_ticks = [150,250,350,450,550]
    df = pd.DataFrame({'value': np.random.random(size=(100,)), 'cat': np.random.choice(ticks, size=(100,))})
    
    fig, (ax1, ax2)= plt.subplots(1,2, figsize=(8,4))
    ax1.set_title('original')
    sns.pointplot(x='cat',y='value',data=df, ax=ax1)
    ax2.set_title('rescaled')
    sns.pointplot(x='cat',y='value',data=df, ax=ax2)
    
    x_ticks = ax2.get_xticks()
    s = (x_ticks[-1]-x_ticks[0])/(ticks[-1]-ticks[0])
    i = x_ticks[0] - s*ticks[0]
    new_x_ticks = s*np.asarray(new_ticks) + i
    
    ax2.set_xticks(new_x_ticks)
    ax2.set_xticklabels(new_ticks)
    

    【讨论】:

    • 我同意您对这是否是个好主意的担忧。这是我的合著者和我来来回回的事情。感谢您提供非常有效的解决方案!
    猜你喜欢
    • 2021-02-22
    • 2021-04-08
    • 1970-01-01
    • 2021-10-27
    • 2015-02-07
    • 2019-08-25
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多