簡體   English   中英

Matplotlib:plot 一條帶有開放標記的線,其中該線在標記內不可見

[英]Matplotlib: plot a line with open markers, where the line is not visible within the markers

我有一個散點圖 plot 顯示一個數據集,其中的符號根據某種色標着色。 我想通過在它們周圍畫一個開放的圓圈並用一條線連接它們來突出其中的幾個點。 換句話說,在一個非常簡化的示例中,我希望結果如下所示:

帶有彩色數據和幾個突出顯示點的散點圖,由一條線連接,其中符號內的線段隱藏在視圖之外 .

我可以使用以下代碼制作一個看起來有點像的 plot:

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(5,5))

X, Y = np.meshgrid(np.arange(10), np.arange(10))
Z = X**2 + Y**2

plt.scatter(X,Y,c=Z, s=300, cmap='viridis_r')

plt.plot([1, 4, 7], [7, 1, 4], 'k-o', linewidth=3, 
         markersize=14, markerfacecolor='none', markeredgewidth=2, 
        )

但是,結果如下所示:

帶有彩色數據和幾個突出顯示點的散點圖,由一條線連接 .

我想要的是讓標記符號的線段從視圖中隱藏。 這是因為我有興趣將注意力吸引到特定的數據點上,並且不想部分地將它們隱藏起來。

解決方法是:

  1. 復制我要突出顯示的數據點,並用與標記隱藏的原始符號完全相同的顏色填充標記。 這並不令人滿意,因為(a)我並不總是可以訪問數據,只能訪問 output 圖形或軸實例,並且(b)在半透明符號的情況下我不知道如何執行此操作,在我的實際數據集中就是這種情況。
  2. 手動計算調整后的坐標以使連接線僅到達標記的邊緣。 這似乎也很不令人滿意(鑒於軸和符號的坐標系不會相同,我不知道如何 go 左右)。

我的問題是:go 的最佳方式是什么? 有沒有比上面的選項 1 和 2 更好的方法,如果沒有,最好的方法是什么? 如前所述,對於 1,我預見到透明度問題(我正在使用),對於 2,我預見到坐標系問題,例如在放大或縮小的情況下等。

(在我的示例中,我有點困惑的另一個小觀察: plt.plotplt.scatter似乎與 plot 的東西在完全相同的位置(參見此圖)並且尺寸定義不一致)

您想要獲得透明(開放)圓,定位在數據坐標中,但半徑以點為單位。 您想將圓圈相互連接,而不是中心點。 這意味着您不能使用法線。 相反,幾個ConnectionPatch可以提供幫助。 您可以將它們縮小一半的標記大小,以便它們接觸圓圈的邊界。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import ConnectionPatch

fig, ax = plt.subplots(figsize=(5,5))

X, Y = np.meshgrid(np.arange(10), np.arange(10))
Z = X**2 + Y**2

ax.scatter(X,Y,c=Z, s=300, cmap='viridis_r')

xc = [1, 4, 7]
yc = [7, 1, 4]

ax.plot(xc, yc, linewidth=0, marker="o", color="black",
         markersize=np.sqrt(300), markerfacecolor='none', markeredgewidth=3)

for i in range(len(xc)-1):
    cp = ConnectionPatch((xc[i],yc[i]), (xc[i+1], yc[i+1]), 
                         coordsA='data', coordsB='data', axesA=ax, axesB=ax,
                         shrinkA=np.sqrt(300)/2, shrinkB=np.sqrt(300)/2,
                         linewidth=2)
    ax.add_patch(cp)

plt.show()

在此處輸入圖像描述

已接受答案的替代方法是對標記使用單獨的散點,對連接使用單獨的線。 使用 z-order,可以確保在主散點 plot 下方繪制線條,並在上方繪制標記。

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(5,5))

X, Y = np.meshgrid(np.arange(10), np.arange(10))
Z = X**2 + Y**2

pts = np.array([[1, 4, 7],
                [7, 1, 4]])

plt.scatter(X, Y, c=Z, s=300, cmap='viridis_r', vmin=Z.min(), vmax=Z.max())
plt.scatter(X[pts[1], pts[0]], Y[pts[1], pts[0]], s=300, c=Z[pts[1], pts[0]],
            marker='o', edgecolor='k', linewidth=2, zorder=20,
            vmin=Z.min(), vmax=Z.max(), cmap='viridis_r')
plt.plot(X[pts[1], pts[0]], Y[pts[1], pts[0]], 'k-', linewidth=2, zorder=10)

我們用另一組標記覆蓋圓圈,而不是facecolor='none' 對兩個散點圖使用vminvmax可確保頂點覆蓋的 colors 與底層圓相同。

在此處輸入圖像描述

暫無
暫無

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

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