質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2805閲覧

PythonのSeabornで棒グラフにhueをつけたときに間隔が空いてしまうのを詰めたい

hacosato

総合スコア48

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/07/25 10:53

編集2021/07/25 15:01

Pythonを使い、Jupyter NotebookでSeabornグラフを描いています。
下記は理想通りの見た目です。

python

1from matplotlib import pyplot as plt 2import seaborn as sns 3import pandas as pd 4 5df = pd.DataFrame({'label': ['A', 'A', 'A', 'A', 'A', 'B', 'B','B', 'B', 'B', ], 'score': [1, 1, 1, 2, 3, 1, 2, 3, 4, 5]}) 6sns.barplot(x='score', y='label', orient='h', data=df 7 # ,hue='label' 8 , palette=sns.color_palette("Set2"))

イメージ説明

コメントアウトしたhueを追加すると、棒グラフの間に間隔が空いてしまい、意図通りではありません。

Python

1from matplotlib import pyplot as plt 2import seaborn as sns 3import pandas as pd 4 5df = pd.DataFrame({'label': ['A', 'A', 'A', 'A', 'A', 'B', 'B','B', 'B', 'B', ], 'score': [1, 1, 1, 2, 3, 1, 2, 3, 4, 5]}) 6sns.barplot(x='score', y='label', orient='h', data=df 7 ,hue='label' 8 , palette=sns.color_palette("Set2"))

イメージ説明
(サンプル用に作ったデータなので色がいっしょなのですが、)実際にはもっとたくさんのデータをまとめたグラフを作りたいと思っており、hueを使いたいです。
hueをつけたときに棒グラフの間隔を開けないようにするにはどうしたらよいですか?

python 3.7.6
matplotlib 3.2.1
seaborn 0.11.1

(追記)
すみません。
サンプルの作り方がよくなかったので再送させてください。
カラムをひとつ追記しました。

Python

1from matplotlib import pyplot as plt 2import seaborn as sns 3import pandas as pd 4 5df = pd.DataFrame({'label': ['A', 'A', 'a', 'a', 'a', 'B', 'B', 'B', 'b', 'b', ], 'case': ['u', 'u', 'l', 'l', 'l', 'u', 'u', 'u', 'l', 'l'], 'score': [1, 1, 1, 2, 3, 1, 2, 3, 4, 5]}) 6sns.barplot(x='score', y='label', orient='h', data=df 7 # ,hue='case' 8 , palette=sns.color_palette("Set2"))

イメージ説明
これを大文字か小文字かでそれぞれ色をつけたいです
(大文字は緑、小文字は赤、のように)。

Python

1from matplotlib import pyplot as plt 2import seaborn as sns 3import pandas as pd 4 5df = pd.DataFrame({'label': ['A', 'A', 'a', 'a', 'a', 'B', 'B', 'B', 'b', 'b', ], 'case': ['u', 'u', 'l', 'l', 'l', 'u', 'u', 'u', 'l', 'l'], 'score': [1, 1, 1, 2, 3, 1, 2, 3, 4, 5]}) 6sns.barplot(x='score', y='label', orient='h', data=df 7 ,hue='case' 8 , palette=sns.color_palette("Set2"))

イメージ説明
これで間隔が詰まればうまくいくかと思いご質問しました。
が、meg_さんのおっしゃる通り、長さ0の棒グラフが挟まっているように見えます。
hueを使うのがそもそもおかしいでしょうか?

(さらに追記)
やりたいことを図にしました。
左の表(DataFrameで渡す)を受け取って、右のグラフを描きたいです。
基本的には横組みの棒グラフですが、caseによってグラフの色を変えたいです。
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

hueの使い方としては下記の様にxyとは別の項目を表示することかと思います。

Python

1df = pd.DataFrame({'label': ['A', 'A', 'A', 'A', 'A', 'B', 'B','B', 'B', 'B'], 'score': [1, 1, 1, 2, 3, 1, 2, 3, 4, 5], 'country':['C', 'D', 'C', 'E', 'D', 'C', 'C','D', 'E', 'C']}) 2ax = sns.barplot(x='score', y='label', orient='h', data=df , hue='country', palette=sns.color_palette("Set2"))

イメージ説明

質問のコードでは見えませんが(データが0なので)各々AとBのバーが存在しているのではないでしょうか?

上記コードでlabel=Aでcountry=Cがない場合は下記グラフとなります。

python

1df = pd.DataFrame({'label': ['A', 'A', 'A', 'A', 'A', 'B', 'B','B', 'B', 'B'], 'score': [1, 1, 1, 2, 3, 1, 2, 3, 4, 5], 'country':['D', 'D', 'D', 'E', 'D', 'C', 'C','D', 'E', 'C']}) 2ax = sns.barplot(x='score', y='label', orient='h', data=df , hue='country', palette=sns.color_palette("Set2"))

イメージ説明


【追記】
matplotlibを使って下記の様な感じでしょうか?

python

1df = pd.DataFrame({'label':['A','a','B','b','C','D','e'],'case':['u','l','u','l','u','u','l'],'score':[134,102,82,112,104,94,122]}) 2 3for i in range(len(df)): 4 if df.loc[i, 'case'] == 'u': 5 plt.barh(df.loc[i, 'label'], df.loc[i, 'score'], color='b') 6 else: 7 plt.barh(df.loc[i, 'label'], df.loc[i, 'score'], color='g') 8plt.legend(['u', 'l']) 9plt.show()

イメージ説明

投稿2021/07/25 11:58

編集2021/07/25 16:14
meg_

総合スコア10898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hacosato

2021/07/25 12:54

ご回答ありがとうございます。 質問が悪かったのでテストデータを作り直しました。申し訳ありません。 たしかに長さ0の棒グラフが挟まっているように見えます……。 hueを使うのがそもそもおかしいでしょうか?
meg_

2021/07/25 13:17

どうしてもseabornを使いたいのでしょうか?matplotlibでは駄目なのでしょうか?
hacosato

2021/07/25 13:19

matplotlibでもいいです! そちらのほうがラクでしょうか?
meg_

2021/07/25 13:25

最初の質問文では凡例を表示させたいのかと思いました。(最初の質問のグラフにおいては意味がなく不要ですが) 追加の質問文も読みましたが、いまいちどんなデータ分析を行いたいのか分かりませんでした。グラフで何を伝えたいのでしょうか?
hacosato

2021/07/25 13:36

棒グラフにcaseというカテゴリカル変数があり、それをグラフの塗り色で表現したいと思っています。 それぞれのlabelはかならずひとつのcaseを持っています。
meg_

2021/07/25 14:15

> 棒グラフにcaseというカテゴリカル変数があり グラフは一旦置いておいて、データをどう分析したいのか考えた方が良いかもしれません。 > それぞれのlabelはかならずひとつのcaseを持っています。 1対1ならlabelそのもので表現可能だと思います。それとも「1つ以上」の間違いですか?
meg_

2021/07/25 14:20 編集

hueを使用すると該当するデータがない場合、「空白がある」ように見えてしまうと思います。これは仕様だと思いますし、詰めてしまうとグラフのバランスが崩れてしまうかと思います。 実際のデータが分からないので違うかもしれませんが、例えば積み上げ棒グラフで表現可能ではありませんか?
hacosato

2021/07/25 15:05

ひとつのlabelはひとつのcaseを持っていますが、ひとつのcaseは複数のlabelに割り当てられることもあるという感じです。 図を描いてみました。 やりたいことは、基本的には横組みの棒グラフですが、caseによってグラフの色を変えたいです。 データの可視化の点ではおかしくないと思っているのですがいかがでしょうか…?
hacosato

2021/07/26 15:36

慣れないmatplotlibに四苦八苦でしたが、教えていただいたやり方で 手持ちのデータにも当てはめることがてきました。 たいへんありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問