9

私の以前の質問と同様に、matplotlib を使用して描画される線の capstyle を制御したいと思います。しかし、非常に多くの線があり、線のコレクション以外で描画す​​ると時間がかかりすぎます。線コレクション内の線の capstyle を一般的な方法で制御する回避策はありますか (または、多数のLine2D線を描画する超高速の方法)。たとえば、次の方法で matplotlib rc 設定を使用してみました。

import matplotlib as mpl
mpl.rcParams['lines.solid_capstyle'] = 'round'
mpl.rcParams['lines.solid_joinstyle'] = 'round'

しかし、これは何の影響もないようです。の docstring からcollections.py:

クラスは、対応する単一要素ほど柔軟であることを意図していません (たとえば、すべての線種を選択できない場合があります) が、一般的な使用例 (実線セグメントの大規模なセットなど) では高速であることを意図しています。

これは、さまざまなパラメーターを制御できないように見える理由を説明していますが、それでもやりたいです! 私はAGGバックエンドのコードを見てきました(_backend_agg.cpp:私はそれを本当に理解しているわけではありません).line_capとline_joinはandによって制御されているようです.gcgc.capはクラスgc.joinから来ています. GCAggPythonからこれを制御する方法を知っている人はいますか? ここで正しい質問をしていますか?おそらく、これらのパラメーターを制御する簡単な方法はありますか?

どんな助けでも大歓迎です...私はこれを機能させるために必死なので、クレイジーなハックでも大歓迎です!

ありがとう、

カーソン

4

3 に答える 3

5

質問で「汚い」ソリューションを気にしないと述べているので、1つのオプションは次のようになります。

特定の「描画プロセス」は、クラス (のベース) で定義されLineCollectionたメソッドによって処理されます。このメソッドは、ステートメントを介して(で定義された) のインスタンスを作成します。とりわけ(property ) を制御するプロパティを管理するのは、まさにこのオブジェクトのようです。したがって、 をサブクラス化し、プロパティをオーバーライドし、新しいメソッドをクラスに注入して、その後の呼び出しでカスタマイズされたインスタンスを返すようにすることができます。drawCollectionLineCollectionGraphicsContextBasebackend_bases.pygc = renderer.new_gc()capstyle_capstyleGraphicsContextBase_capstylenew_gcRendererBasenew_gc

@florisvb の回答から例を借ります (Python3 を想定):

#!/usr/bin/env python
import types

import numpy as np
from matplotlib.backend_bases import GraphicsContextBase, RendererBase
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

class GC(GraphicsContextBase):
    def __init__(self):
        super().__init__()
        self._capstyle = 'round'

def custom_new_gc(self):
    return GC()

RendererBase.new_gc = types.MethodType(custom_new_gc, RendererBase)
#----------------------------------------------------------------------
np.random.seed(42)

x = np.random.random(10)
y = np.random.random(10)

points = np.array([x, y]).T.reshape((-1, 1, 2))
segments = np.concatenate([points[:-1], points[1:]], axis=1)

fig = plt.figure()
ax = fig.add_subplot(111)

linewidth = 10
lc = LineCollection(segments, linewidths=linewidth)
ax.add_collection(lc)

fig.savefig('fig.png')

これにより、次が生成されます。 ここに画像の説明を入力

于 2017-05-14T09:58:06.693 に答える