第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Matplotlib:每次繪制圖形時調(diào)用的自定義函數(shù)

Matplotlib:每次繪制圖形時調(diào)用的自定義函數(shù)

紫衣仙女 2021-07-07 17:09:21
我想創(chuàng)建一個包含箭頭的matplotlib圖,其頭部的形狀與數(shù)據(jù)坐標(biāo)無關(guān)。這類似于FancyArrowPatch,但是當(dāng)箭頭長度小于頭部長度時,會收縮以適應(yīng)箭頭的長度。目前,我通過將寬度轉(zhuǎn)換為顯示坐標(biāo)、計算顯示坐標(biāo)中的頭部長度并將其轉(zhuǎn)換回數(shù)據(jù)坐標(biāo)來設(shè)置箭頭的長度來解決這個問題。只要軸的尺寸不發(fā)生變化,這種方法就可以很好地工作,這可能是由于set_xlim(),set_ylim()或tight_layout()例如。我想通過在繪圖尺寸發(fā)生變化時重新繪制箭頭來涵蓋這些情況。目前我通過注冊一個函數(shù)on_draw(event)來處理這個axes.get_figure().canvas.mpl_connect("resize_event", on_draw)但這僅適用于交互式后端。我還需要一個解決方案,將繪圖保存為圖像文件。還有其他地方可以注冊我的回調(diào)函數(shù)嗎?
查看完整描述

2 回答

?
Helenr

TA貢獻1780條經(jīng)驗 獲得超4個贊

我找到了該問題的解決方案,但是,它不是很優(yōu)雅。我發(fā)現(xiàn),在非交互式后端調(diào)用的唯一回調(diào)函數(shù)是子類的draw_path()方法AbstractPathEffect。


我創(chuàng)建了一個AbstractPathEffect子類,在其draw_path()方法中更新箭頭的頂點。


我仍然愿意為我的問題提供其他可能更直接的解決方案。


import numpy as np

from numpy.linalg import norm

from matplotlib.patches import FancyArrow

from matplotlib.patheffects import AbstractPathEffect


class AdaptiveFancyArrow(FancyArrow):

    """

    A `FancyArrow` with fixed head shape.

    The length of the head is proportional to the width the head

    in display coordinates.

    If the head length is longer than the length of the entire

    arrow, the head length is limited to the arrow length.

    """


    def __init__(self, x, y, dx, dy,

                 tail_width, head_width, head_ratio, draw_head=True,

                 shape="full", **kwargs):

        if not draw_head:

            head_width = tail_width

        super().__init__(

            x, y, dx, dy,

            width=tail_width, head_width=head_width,

            overhang=0, shape=shape,

            length_includes_head=True, **kwargs

        )

        self.set_path_effects(

            [_ArrowHeadCorrect(self, head_ratio, draw_head)]

        )



class _ArrowHeadCorrect(AbstractPathEffect):

    """

    Updates the arrow head length every time the arrow is rendered

    """


    def __init__(self, arrow, head_ratio, draw_head):

        self._arrow = arrow

        self._head_ratio = head_ratio

        self._draw_head = draw_head


    def draw_path(self, renderer, gc, tpath, affine, rgbFace=None):

        # Indices to certain vertices in the arrow

        TIP = 0

        HEAD_OUTER_1 = 1

        HEAD_INNER_1 = 2

        TAIL_1 = 3

        TAIL_2 = 4

        HEAD_INNER_2 = 5

        HEAD_OUTER_2 = 6


        transform = self._arrow.axes.transData


        vert = tpath.vertices

        # Transform data coordiantes to display coordinates

        vert = transform.transform(vert)

        # The direction vector alnog the arrow

        arrow_vec = vert[TIP] - (vert[TAIL_1] + vert[TAIL_2]) / 2

        tail_width = norm(vert[TAIL_2] - vert[TAIL_1])

        # Calculate head length from head width

        head_width = norm(vert[HEAD_OUTER_2] - vert[HEAD_OUTER_1])

        head_length = head_width * self._head_ratio

        if head_length > norm(arrow_vec):

            # If the head would be longer than the entire arrow,

            # only draw the arrow head with reduced length

            head_length = norm(arrow_vec)

        # The new head start vector; is on the arrow vector

        if self._draw_head:

            head_start = \

            vert[TIP] - head_length * arrow_vec/norm(arrow_vec)

        else:

            head_start = vert[TIP]

        # vector that is orthogonal to the arrow vector

        arrow_vec_ortho = vert[TAIL_2] - vert[TAIL_1]

        # Make unit vector

        arrow_vec_ortho = arrow_vec_ortho / norm(arrow_vec_ortho)

        # Adjust vertices of the arrow head

        vert[HEAD_OUTER_1] = head_start - arrow_vec_ortho * head_width/2

        vert[HEAD_OUTER_2] = head_start + arrow_vec_ortho * head_width/2

        vert[HEAD_INNER_1] = head_start - arrow_vec_ortho * tail_width/2

        vert[HEAD_INNER_2] = head_start + arrow_vec_ortho * tail_width/2

        # Transform back to data coordinates

        # and modify path with manipulated vertices

        tpath.vertices = transform.inverted().transform(vert)

        renderer.draw_path(gc, tpath, affine, rgbFace)



查看完整回答
反對 回復(fù) 2021-07-21
  • 2 回答
  • 0 關(guān)注
  • 383 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號