1

Matlab から切り替えて、Matplotlib を使い始めたばかりです。Windows 7 で python(x,y) を介して Spyder を実行しています。

私は小さなスクリプトを書きました。

  • 表形式のデータを含む複数の Excel スプレッドシートを開く
  • 各シートについて、いくつかの円グラフを生成します - それぞれが Excel からの 1 行のデータを要約します
  • PdfPagesバックエンドを使用して、出力ドキュメントの独自のページに円グラフの各グループをプロットします。

すべての円グラフは同じ凡例を共有するため、各シートに "共有" 凡例を 1 つだけ表示したいと考えました。私が見つけた解決策を次に示します: matplotlib - Legend in separate subplot 各円グラフを独自の に配置subplotし、別のペインに「ダミー」円を生成し、凡例を生成してから、 を使用して円のすべての部分を非表示にしset_visible(False)ます。

最初のループ反復 (つまり、最初の Excel スプレッドシートと円グラフの最初のページ) は問題ありませんでした。ただし、後続のループでは、テキスト ラベルを含む凡例が生成されましたが、色付きのボックスは生成されませんでした。例は、次の Imgur リンクに示されています (申し訳ありませんが、私は Stackoverflow を初めて使用するため、まだ画像を投稿できません)。http://i.imgur.com/0ssak1O.png

この問題は、PdfPagesバックエンドによって生成された出力に影響しているようですが、デフォルトのグラフィカル バックエンドには影響していないTkAggようです ( ? Spyder がデフォルトで使用するものがわからない)。コメントアウトしPDFfile.savefig()てコメントを外すと、以下の簡略化されたスクリプトでこれを確認できますplt.show()

.set_visible()つまり、要約すると、この問題はループ全体でメソッドが「記憶」されていることに起因しているように見えますがPdfPages、グラフィカルなものではなく、バックエンドに影響します。私は完全に混乱していますが、この投稿が他の人にとって意味があることを願っています. どんな助けでも感謝します:-)

import xlrd, numpy as np, matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages


PDFfile = PdfPages('output.pdf')


for i in range(4):

        pieData = [
                   [1, 2, 3, 4],
                   [5, 6, 7, 8],
                   [9, 0, 1, 2]]

        pieSliceLabels = ['A', 'B', 'C', 'D']
        pieLabels = ['1', '2', '3']

        # now, generate some pie plots

        plt.figure(0, figsize=(6,2))

        numPies = len(pieLabels)  

        for thisPie in range(numPies):
                ax = plt.subplot(1,4,1+thisPie)
                plt.title(pieLabels[thisPie])                
                fracs = pieData[thisPie]
                plt.pie(fracs)



        # Since all three pie plots share the same data labels, I'd rather just
        # generate a single legend that they all share.
        # The method I used comes from here:
        # https://stackoverflow.com/questions/11140311/matplotlib-legend-in-separate-subplot

        # First, generate a "dummy pie" containing same data as last pie.
        plt.subplot(1,4,4)
        DummyPie = plt.pie(fracs)

        # next, generate a big ol' legend
        plt.legend(pieSliceLabels, loc='center',prop={'size':'small'})

        # finally, hide the pie.
        for Pieces in DummyPie:
                for LittlePiece in Pieces:
                    LittlePiece.set_visible(False)



        # NOW, HERE'S WHERE IT GETS WEIRD...

        # Leave the following line uncommented:
        PDFfile.savefig()
        # ... and a PDF is generated where the legend colors are shown
        # properly on the first page, but not thereafter!

        # On the other hand.... comment out "PDF.savefig()" above, and
        # uncomment the following line:
        # plt.show()
        # ...and the figures will be generated onscreen, WITHOUT the legend
        # problem!!



PDFfile.close()
4

1 に答える 1

0

バックエンドにしか表示されないのは奇妙PdfPagesですが、同じ Figure オブジェクトをクリアせずに再利用しているためです。

毎回新しいフィギュアを作るのが一番です。PDF に多数のページが含まれる場合は、図を 1 つだけ使用し、毎回消去する方が理にかなっている場合があります (例:plt.clf()またはfig.clf())。

ただ電話してみてください:

plt.figure(figsize=(6,2))

それ以外の:

plt.figure(0, figsize=(6,2))

また、円グラフが「押しつぶされた」ように見えたくない場合は、サブプロットの縦横比を 1 (ax.axis('equal')またはplt.axis('equal').


編集:これは、matplotlib への OO インターフェイスを使用する例です。これにより、追跡が少し簡単になります。imo:

import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

pie_data = [[1, 2, 3, 4],
            [5, 6, 7, 8],
            [9, 0, 1, 2]]
pie_slice_labels = ['A', 'B', 'C', 'D']
pie_labels = ['1', '2', '3']

PDFfile = PdfPages('output.pdf')

for i in range(4):
    fig, axes = plt.subplots(ncols=len(pie_labels) + 1, figsize=(6,2))

    for ax, data, label in zip(axes, pie_data, pie_labels):
        wedges, labels = ax.pie(data)
        ax.set(title=label, aspect=1)

    # Instead of creating a dummy pie, just use the artists from the last one.
    axes[-1].legend(wedges, pie_slice_labels, loc='center', fontsize='small')
    axes[-1].axis('off')
    # Alternately, you could do something like this to place the legend. If you
    # use this, you should remove the +1 from ncols above. 
    # fig.legend(wedges, pie_slice_labels, loc='center right', fontsize='small')
    # fig.subplots_adjust(right=0.8) # Make room for the legend.

    PDFfile.savefig()

PDFfile.close()
于 2013-02-01T13:01:52.457 に答える