定制与散点图传奇

问题描述 投票:0回答:2

我与我的定制散点图的传奇奋斗。这里是一个快照:

Fun with MatPlotLib

这里是一个代码示例:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set()

my_df = pd.DataFrame([[5, 3, 1], [2, 1, 2], [3, 4, 1], [1, 2, 1]],
                     columns=["DUMMY_CT", "FOO_CT", "CI_CT"])

g = sns.scatterplot("DUMMY_CT", "FOO_CT", data=my_df, size="CI_CT")
g.set_title("Number of Baz", weight="bold")
g.set_xlabel("Dummy count")
g.set_ylabel("Foo count")
g.get_legend().set_title("Baz count")

另外,我在Jupyter实验室笔记本工作在Python 3,如果有帮助。

The red thingy issue

首先第一件事情,我想隐藏CI_CT变量的名称(轮廓为红色的图片)。游览整个文档今天下午之后,我发现get_legend_handlers_label方法(见here),这将产生以下:

>>> g.get_legend_handles_labels()
([<matplotlib.collections.PathCollection at 0xfaaba4a8>,
  <matplotlib.collections.PathCollection at 0xfaa3ff28>,
  <matplotlib.collections.PathCollection at 0xfaa3f6a0>,
  <matplotlib.collections.PathCollection at 0xfaa3fe48>],
  ['CI_CT', '0', '1', '2'])

我在哪里能发现我亲爱的CI_CT字符串。然而,我无法改变这个名字,或完全隐藏。我发现了一个肮脏的方式,基本上在于不使用有效的data参数传递的数据帧。这里是scatterplot电话:

g = sns.scatterplot("DUMMY_CT", "FOO_CT", data=my_df, size=my_df["CI_CT"].values)

结果在这里:

First issue solved in a dirty way

它的工作原理,但有一个更清洁的方式来实现这一目标?

The green thingy issue

显示在这个传奇0水平是不正确,因为在CI_CT的列my_df没有零值。因此,它会误导读者,谁可能承担更小的点表示0或者1的值。我想设置一个定义的比例,在一个能做到这一点的X和Y轴的方式。但是,我不能达到它。任何想法?

TL;DR : A broader question that could solve everything

那些冒险让我不知道是否有处理,你可以通过与huesize参数散点图在干净,X轴和Y轴的方式数据的方式。它实际上是可能的吗?

请原谅我的英语水平,请让我知道如果问题过于宽泛或uncorrectly标记。

pandas matplotlib seaborn
2个回答
1
投票

“绿色的东西问题”,即还有一个图例项比有大小,通过指定legend="full"解决。

g = sns.scatterplot(..., legend="full")

在“红色的东西问题”更棘手。这里的问题是,seaborn误用正常的图例标签的图例标题。一种选择是确实直接提供,而不是列名的值,以防止seaborn使用该列名。

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set()

my_df = pd.DataFrame([[5, 3, 1], [2, 1, 2], [3, 4, 1], [1, 2, 1]],
                     columns=["DUMMY_CT", "FOO_CT", "CI_CT"])

g = sns.scatterplot("DUMMY_CT", "FOO_CT", data=my_df, size=my_df["CI_CT"].values, legend="full")
g.set_title("Number of Baz", weight="bold")
g.set_xlabel("Dummy count")
g.set_ylabel("Foo count")
g.get_legend().set_title("Baz count")

plt.show()

enter image description here

如果你真的必须使用列名本身,哈克的解决办法是爬进传说,并删除你不想要的标签。

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set()

my_df = pd.DataFrame([[5, 3, 1], [2, 1, 2], [3, 4, 1], [1, 2, 1]],
                     columns=["DUMMY_CT", "FOO_CT", "CI_CT"])

g = sns.scatterplot("DUMMY_CT", "FOO_CT", data=my_df, size="CI_CT", legend="full")
g.set_title("Number of Baz", weight="bold")
g.set_xlabel("Dummy count")
g.set_ylabel("Foo count")
g.get_legend().set_title("Baz count")

#Hack to remove the first legend entry (which is the undesired title)
vpacker = g.get_legend()._legend_handle_box.get_children()[0]
vpacker._children = vpacker.get_children()[1:]

plt.show()

0
投票

我终于设法得到的结果我想,但丑陋的方式。这可能是有用的人,但我不会建议这样做。

将溶液以固定皮进入图例由所有CI_CT列值移动到底片的(保持顺序和标记尺寸的一致性)。然后,在图例中显示的值被相应地校正到先前数据的变化(从here灵感)。

但是,我没有找到什么更好的办法,使在传说中的“CI_CT”文本消失,不留一个残暴巨大空白。

下面是代码和结果的样品。

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set()

my_df = pd.DataFrame([[5, 3, 1], [2, 1, 2], [3, 4, 1], [1, 2, 1]], columns=["DUMMY_CT", "FOO_CT", "CI_CT"])

# Substracting the maximal value of CI_CT for each value
max_val = my_df["CI_CT"].agg("max")
my_df["CI_CT"] = my_df.apply(lambda x : x["CI_CT"] - max_val, axis=1)

# scatterplot declaration
g = sns.scatterplot("DUMMY_CT", "FOO_CT", data=my_df, size=my_df["CI_CT"].values)
g.set_title("Number of Baz", weight="bold")
g.set_xlabel("Dummy count")
g.set_ylabel("Foo count")
g.get_legend().set_title("Baz count")

# Correcting legend values
l = g.legend_
for t in l.texts :
    t.set_text(int(t.get_text()) + max_val)

# Restoring the DF
my_df["CI_CT"] = my_df.apply(lambda x : x["CI_CT"] + max_val, axis=1)

Fancy yet badly produced scatterplot

我还在寻找一个更好的方式来实现这一目标。

© www.soinside.com 2019 - 2024. All rights reserved.