簡體   English   中英

在海洋圖上設置剪輯

[英]Setting a clip on a seaborn plot

我在裁剪seaborn (特別是kdeplot )時遇到了麻煩,因為我認為matplotlib docs中的每個示例都非常簡單。

例如,以下代碼:

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

fig = plt.figure()
ax = fig.add_subplot(111, frameon=False, xticks=[], yticks=[])

random_points = np.array([p for p in np.random.random(size=(100, 2)) if 0 < p[0] < 1 and 0 < p[1] < 1])

kde = sns.kdeplot(random_points[:,0], random_points[:,1], ax=ax)

xmin, xmax = kde.get_xlim()
ymin, ymax = kde.get_ylim()

patch = mpl.patches.Circle(((xmin + xmax)/2, (ymin + ymax) / 2), radius=0.4)
ax.add_patch(patch)
kde.set_clip_path(patch)

結果如下:

在此處輸入圖片說明

我想剪輯此結果,以使KDE輪廓線不會出現在圓之外。 到目前為止,我還沒有找到一種方法...這可能嗎?

Serenity的答案適用於簡單的形狀,但是當形狀包含三個以上左右的頂點時(由於我甚至很難建立確切的參數),由於不明的原因而無法解決。 對於足夠大的形狀,填充物流入邊緣應位於的位置, 例如此處

但是,這確實讓我思考了正確的道路。 雖然似乎不可能僅使用matplotlib來做到這一點(無論他提供的代碼中是否有錯誤?),但在使用shapely庫時就很容易做到這一點,這適用於此類任務。

產生形狀

在這種情況下,您將需要shapely的symmetric_difference方法。 對稱差異是此切除操作的設定理論名稱。

在此示例中,我已將曼哈頓形多邊形加載為shapely.geometry.Polygon對象。 我不會在這里介紹初始化過程,這很容易做到,而且您期望的一切都將如此。

我們可以使用manhattan.envelopemanhattan周圍繪制一個框,然后應用差異。 這是以下內容:

unmanhattan = manhattan.envelope.symmetric_difference(manhattan)

這樣做使我們能夠:

在此處輸入圖片說明

將其添加到繪圖中

好的,但這是一個shapely對象,而不是matplotlib Patch ,我們如何將其添加到繪圖中? descartes庫處理此轉換。

unmanhattan_patch = descartes.PolygonPatch(unmanhattan)

這就是我們所需要的! 現在我們做:

unmanhattan_patch = descartes.PolygonPatch(unmanhattan)
ax.add_patch(unmanhattan_patch)
sns.kdeplot(x=points['x_coord'], y=points['y_coord'], ax=ax)

得到:

在此處輸入圖片說明

並通過更多工作將其擴展到視圖中的其余多邊形(紐約市),我們可以得到以下最終結果:

在此處輸入圖片說明

我想您的示例僅適用於“ imshow”。

要隱藏圓上的輪廓線,必須繪制所需顏色的“反”多邊形。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import seaborn as sns

# Color plot except polygon
def mask_outside(poly_verts, facecolor = None, ax = None):
    from matplotlib.patches import PathPatch
    from matplotlib.path import Path

    if ax is None: ax = plt.gca()
    if facecolor is None: facecolor = plt.gcf().get_facecolor()

    # Construct inverse polygon
    xlim, ylim = ax.get_xlim(), ax.get_ylim()
    bound_verts = [(xlim[0], ylim[0]), (xlim[0], ylim[1]), 
                   (xlim[1], ylim[1]), (xlim[1], ylim[0]), (xlim[0], ylim[0])]
    bound_codes = [Path.MOVETO] + (len(bound_verts) - 1) * [Path.LINETO]
    poly_codes = [Path.MOVETO] + (len(poly_verts) - 1) * [Path.LINETO]

    # Plot it
    path = Path(bound_verts + poly_verts, bound_codes + poly_codes)
    ax.add_patch(PathPatch(path, facecolor = facecolor, edgecolor = 'None', zorder = 1e+3))

# Your example
fig = plt.figure()
ax = fig.add_subplot(111, frameon=False, xticks=[], yticks=[])
random_points = np.array([p for p in np.random.random(size=(100, 2)) if 0 < p[0] < 1 and 0 < p[1] < 1])
kde = sns.kdeplot(random_points[:,0], random_points[:,1], ax=ax)

xmin, xmax = kde.get_xlim()
ymin, ymax = kde.get_ylim()

patch = mpl.patches.Circle(((xmin + xmax) / 2, (ymin + ymax) / 2), radius=0.4)
mask_outside([tuple(x) for x in patch.get_verts()]) # call before add_patch!
ax.add_patch(patch)

plt.show()

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM