【问题标题】:How to position a rectangle to highlight categorical data?如何定位矩形以突出显示分类数据?
【发布时间】:2020-05-13 12:30:04
【问题描述】:

我想绘制矩形以及数据的 x 轴分类值。

一些类似但不是我要找的帖子。

matplotlib: how to draw a rectangle on image

Plotting shapes in Matplotlib through a loop

Weird behavior of matplotlib plt.Rectangle

这些是预期的输出;

我想将矩形移动到每个后续的 x 值。并单独保存所有图像。

上图的代码(带有矩形的初步代码):

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt   

data = pd.DataFrame(raw_data, columns = ['first_name', 'pre_score'])

order = np.sort(data['first_name'].unique())

save_images = r'D:\test'

for x_names in order:

    print(x_names)

    sns.set_style("ticks")
    ax = sns.stripplot(x='first_name', y='pre_score', hue='first_name',order=order, jitter=True, dodge=False, size=6, zorder=0, alpha=0.5, linewidth =1, data=data)
    ax = sns.boxplot(x='first_name', y='pre_score', hue='first_name',order=order, dodge=False, showfliers=True, linewidth=0.8, showmeans=True, width=0.28, data=data)
    ax = sns.pointplot(x='first_name', y='pre_score', order=order, data=data, ci=None, color='black')
    fig_size = [18.0, 10.0]
    plt.rcParams["figure.figsize"] = fig_size
    ax.yaxis.set_tick_params(labelsize=14)
    ax.xaxis.set_tick_params(labelsize=14)

    plt.Rectangle((0, 0), 0.28, max(data['pre_score']), color="red");

    # ax.add_patch(plt.Rectangle(x_names, fill=False, linewidth=2.0))

    plt.savefig(save_images +x_names+'.png', dpi=150,bbox_inches="tight")

在@JohanC 之后得到了这个

【问题讨论】:

  • 你目前得到了什么?没有raw_data 信息,我无法生成当前绘图。
  • @SathishSanjeevi 原始数据在底部!
  • 与此相比,额外的难度是多少? stackoverflow.com/questions/37435369/…

标签: python matplotlib


【解决方案1】:

主要问题似乎是如何计算围绕每一列的矩形的坐标。

Rectangle的参数为Rectangle((x, y), width, height, ...

使用分类数据时,每个名称的 x 位置是索引 0, 1, 2, ...。 两个连续名称之间的 x 距离为 1.0,因此可以使用稍小的数字作为矩形的宽度。名称的 x 位置正好在其框的中心。为了得到一个居中的矩形,我们可以将它定位在 x 减去宽度的一半。

对于 y 位置和高度,我们可以取坐标轴限制,并减去一些填充。

在下面的代码中生成了一些随机数据。此外,figsize 是在调用绘图之前设置的。

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

N = 100
raw_names = np.random.choice(['Amy', 'Jake', 'Jason', 'Molly', 'Tina'], N)
raw_scores = np.random.uniform(0, 95, N)

data = pd.DataFrame({'first_name':raw_names, 'pre_score': raw_scores})
order = np.sort(data['first_name'].unique())
save_images = r'D:\test'

plt.rcParams["figure.figsize"] = [18.0, 10.0]

for name_ind, x_names in enumerate(order):
    np.random.seed(123456) # to get the same random stripplot everytime
    sns.set_style("ticks")
    ax = sns.stripplot(x='first_name', y='pre_score', hue='first_name', order=order, jitter=True, dodge=False, size=6, zorder=0, alpha=0.5, linewidth=1, data=data)
    ax = sns.boxplot(x='first_name', y='pre_score', hue='first_name', order=order, dodge=False, showfliers=True, linewidth=0.8, showmeans=True,width=0.28, data=data)
    ax = sns.pointplot(x='first_name', y='pre_score', order=order, data=data, ci=None, color='black')
    ax.yaxis.set_tick_params(labelsize=14)
    ax.xaxis.set_tick_params(labelsize=14)

    ymin, ymax = plt.ylim()
    height = ymax - ymin
    width = 0.7
    ax.add_patch(plt.Rectangle((name_ind - width / 2, ymin + height * 0.02), width, height * 0.96,
                               edgecolor='crimson', fill=False))

    plt.legend(loc='upper left', title='', bbox_to_anchor=[1.01, 0, 1, 1])

    plt.savefig(save_images+x_names+'.png', dpi=150, bbox_inches="tight")
    plt.clf()
    # plt.tight_layout(pad=2)
    # plt.show()

【讨论】:

  • 非常感谢。我可以有沿 x_axis 值的矩形。 OTH,就我而言,最后我为每个轴绘制了所有矩形。我需要的是随着 x 值的变化删除前一个矩形。您是如何在解决方案中获得图像的?
  • 这太棒了。非常感谢您努力解释细节。还有一个小问题,我意识到对于每个情节,箱形图中的点都会发生一些变化。虽然它们在同一个 y 轴上,但有些人可能会抱怨:)这是什么原因?
  • stripplot 随机生成 5 次,for 循环每通过一次。通过在循环开始时显式初始化随机种子,我们将获得相同的随机点。
  • 好的,我知道了。谢谢!
猜你喜欢
  • 2011-10-01
  • 2012-12-24
  • 1970-01-01
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多