27

このようなもの: ここに画像の説明を入力

R でそれを行うための非常に優れたパッケージがあります。Pythonでは、パッケージを使用してこれを理解できるのが最善です( treemaps の実行方法に関する投稿にsquarify触発されました):

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns # just to have better line color and width
import squarify
# for those using jupyter notebooks
%matplotlib inline 


df = pd.DataFrame({
                  'v1': np.ones(100), 
                  'v2': np.random.randint(1, 4, 100)})
df.sort_values(by='v2', inplace=True)

# color scale
cmap = mpl.cm.Accent
mini, maxi = df['v2'].min(), df['v2'].max()
norm = mpl.colors.Normalize(vmin=mini, vmax=maxi)
colors = [cmap(norm(value)) for value in df['v2']]

# figure
fig = plt.figure()
ax = fig.add_subplot(111, aspect="equal")
ax = squarify.plot(df['v1'], color=colors, ax=ax)
ax.set_xticks([])
ax.set_yticks([]);

ワッフル

しかし、100 個ではなく 200 個の要素 (またはその他の非正方形の数) を作成すると、正方形がずれてしまいます。

ここに画像の説明を入力

もう 1 つの問題は、v2 を何らかのカテゴリ変数 (たとえば、100 の As、B、C、および D) に変更すると、次のエラーが発生することです。

文字列を float に変換できませんでした: 'a'

だから、誰でもこれらの2つの質問で私を助けることができます:

  • 非平方数の観測値でアライメントの問題を解決するにはどうすればよいですか?
  • v2でカテゴリ変数を使用するにはどうすればよいですか?

これを超えて、ワッフルプロットをより効率的に作成できる他のpythonパッケージがあれば、私は本当にオープンです.

4

3 に答える 3

14

以下に実際の例をまとめました。これはあなたのニーズを満たすと思います。このアプローチを完全に一般化するためには、多少の作業が必要ですが、それが良い出発点であることがわかると思います。秘訣はmatshow()、非正方形の問題を解決するために使用し、カスタムの凡例を作成してカテゴリ値を簡単に説明することでした。

import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

# Let's make a default data frame with catagories and values.
df = pd.DataFrame({ 'catagories': ['cat1', 'cat2', 'cat3', 'cat4'], 
                    'values': [84911, 14414, 10062, 8565] })
# Now, we define a desired height and width.
waffle_plot_width = 20
waffle_plot_height = 7

classes = df['catagories']
values = df['values']

def waffle_plot(classes, values, height, width, colormap):

    # Compute the portion of the total assigned to each class.
    class_portion = [float(v)/sum(values) for v in values]

    # Compute the number of tiles for each catagories.
    total_tiles = width * height
    tiles_per_class = [round(p*total_tiles) for p in class_portion]

    # Make a dummy matrix for use in plotting.
    plot_matrix = np.zeros((height, width))

    # Popoulate the dummy matrix with integer values.
    class_index = 0
    tile_index = 0

    # Iterate over each tile.
    for col in range(waffle_plot_width):
        for row in range(height):
            tile_index += 1

            # If the number of tiles populated is sufficient for this class...
            if tile_index > sum(tiles_per_class[0:class_index]):

                # ...increment to the next class.
                class_index += 1       

            # Set the class value to an integer, which increases with class.
            plot_matrix[row, col] = class_index

    # Create a new figure.
    fig = plt.figure()

    # Using matshow solves your "non-square" problem. 
    plt.matshow(plot_matrix, cmap=colormap)
    plt.colorbar()

    # Get the axis.
    ax = plt.gca()

    # Minor ticks
    ax.set_xticks(np.arange(-.5, (width), 1), minor=True);
    ax.set_yticks(np.arange(-.5, (height), 1), minor=True);

    # Gridlines based on minor ticks
    ax.grid(which='minor', color='w', linestyle='-', linewidth=2)

    # Manually constructing a legend solves your "catagorical" problem.
    legend_handles = []
    for i, c in enumerate(classes):
        lable_str = c + " (" + str(values[i]) + ")"
        color_val = colormap(float(i+1)/len(classes))
        legend_handles.append(mpatches.Patch(color=color_val, label=lable_str))

    # Add the legend. Still a bit of work to do here, to perfect centering.
    plt.legend(handles=legend_handles, loc=1, ncol=len(classes),
               bbox_to_anchor=(0., -0.1, 0.95, .10))

    plt.xticks([])
    plt.yticks([])

# Call the plotting function.
waffle_plot(classes, values, waffle_plot_height, waffle_plot_width,
            plt.cm.coolwarm)

以下は、このスクリプトが生成する出力の例です。ご覧のとおり、私にとってはかなりうまく機能し、あなたが述べたすべてのニーズを満たしています。問題が発生した場合はお知らせください。楽しみ!

ワッフルプロット

于 2017-01-03T09:59:40.430 に答える