How do you glue a text to a point?Controlling the 2D $x–y$ aspect ratio of a 3D plotLabeling points on a graph with their coordinates in parenthesesKeeping Font Relative Size to Object/Graphics/Plot Object upon ResizeAdding annotations to plot with vertical leader line to the curvearrows labeled with arbitrary expressionsLabeling data in ListPlotHow to scale a vertical quantity (e.g., scaled offset) with the width of a plot?PlotLabel colliding with AxesLabelLabelingFunction won't show all the labelsHow can I replace x-axis labels with pre-determined symbols?

How can I automate this tensor computation?

We get more abuse than anyone else

Three Subway Escalators

Do pedestrians imitate auto traffic?

Is it possible to invoke "super" with less ambiguous results?

Brute-force the switchboard

Is encryption still applied if you ignore the SSL certificate warning for self-signed certs?

BritRail England Passes compared to return ticket for travel in England

Why does a tetrahedral molecule like methane have a dipole moment of zero?

Should I have shared a document with a former employee?

Who would use the word "manky"?

Inscriptio Labyrinthica

Tuning G3 string to A3 guitar

Why is the Intel 8086 CPU called a 16-bit CPU?

Diagram of Methods to Solve Differential Equations

🍩🔔🔥Scrambled emoji tale⚛️🎶🛒 #2️⃣

Locked-up DOS computer beeped on keypress. What mechanism caused that?

Why is Google approaching my VPS machine?

Could a US citizen born through "birth tourism" become President?

Which GPUs to get for Mathematical Optimization (if any)?

When will the last unambiguous evidence of mankind disappear?

Who determines when road center lines are solid or dashed?

Why didn't Doctor Strange restore Tony Stark after he used the Stones?

Difference between class and struct in with regards to padding and inheritance



How do you glue a text to a point?


Controlling the 2D $x–y$ aspect ratio of a 3D plotLabeling points on a graph with their coordinates in parenthesesKeeping Font Relative Size to Object/Graphics/Plot Object upon ResizeAdding annotations to plot with vertical leader line to the curvearrows labeled with arbitrary expressionsLabeling data in ListPlotHow to scale a vertical quantity (e.g., scaled offset) with the width of a plot?PlotLabel colliding with AxesLabelLabelingFunction won't show all the labelsHow can I replace x-axis labels with pre-determined symbols?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








9












$begingroup$


I have a point 0,0 which I call A, and a point 2,1 which I call B. I want to make an image that looks like the one below.



enter image description here



When I resize the image I want the text labels to follow the points, so that the distances from labels to the points remain the same.



I tried with the following code



p0 = Point[0, 0];
p1 = Point[2, 1];
Graphics[p0, Text["A", Offset[-5, -5]], p1,
Text["B", Offset[160, 80]], ImageSize -> 200, 100]


but as you can see, while the A label seems to be glued to p0 the B label is not glued to the p1.



enter image description here



So my question is how do you glue text labels to points so that when points are moved the text labels follow along.










share|improve this question











$endgroup$


















    9












    $begingroup$


    I have a point 0,0 which I call A, and a point 2,1 which I call B. I want to make an image that looks like the one below.



    enter image description here



    When I resize the image I want the text labels to follow the points, so that the distances from labels to the points remain the same.



    I tried with the following code



    p0 = Point[0, 0];
    p1 = Point[2, 1];
    Graphics[p0, Text["A", Offset[-5, -5]], p1,
    Text["B", Offset[160, 80]], ImageSize -> 200, 100]


    but as you can see, while the A label seems to be glued to p0 the B label is not glued to the p1.



    enter image description here



    So my question is how do you glue text labels to points so that when points are moved the text labels follow along.










    share|improve this question











    $endgroup$














      9












      9








      9


      1



      $begingroup$


      I have a point 0,0 which I call A, and a point 2,1 which I call B. I want to make an image that looks like the one below.



      enter image description here



      When I resize the image I want the text labels to follow the points, so that the distances from labels to the points remain the same.



      I tried with the following code



      p0 = Point[0, 0];
      p1 = Point[2, 1];
      Graphics[p0, Text["A", Offset[-5, -5]], p1,
      Text["B", Offset[160, 80]], ImageSize -> 200, 100]


      but as you can see, while the A label seems to be glued to p0 the B label is not glued to the p1.



      enter image description here



      So my question is how do you glue text labels to points so that when points are moved the text labels follow along.










      share|improve this question











      $endgroup$




      I have a point 0,0 which I call A, and a point 2,1 which I call B. I want to make an image that looks like the one below.



      enter image description here



      When I resize the image I want the text labels to follow the points, so that the distances from labels to the points remain the same.



      I tried with the following code



      p0 = Point[0, 0];
      p1 = Point[2, 1];
      Graphics[p0, Text["A", Offset[-5, -5]], p1,
      Text["B", Offset[160, 80]], ImageSize -> 200, 100]


      but as you can see, while the A label seems to be glued to p0 the B label is not glued to the p1.



      enter image description here



      So my question is how do you glue text labels to points so that when points are moved the text labels follow along.







      graphics labeling interactive






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jul 10 at 7:10









      Kuba

      110k12 gold badges217 silver badges555 bronze badges




      110k12 gold badges217 silver badges555 bronze badges










      asked Jul 10 at 7:01









      Bob UelandBob Ueland

      5392 silver badges14 bronze badges




      5392 silver badges14 bronze badges




















          4 Answers
          4






          active

          oldest

          votes


















          8












          $begingroup$

          First of all your Offset specification is strange, I'd make it Offset[-5, -5, 2, 1], right?



          Then, you can use GraphicsGroup to treat it as a single item for the purpose of interactive editing:



          p0 = Point[0, 0];
          p1 = Point[2, 1];
          Graphics[
          GraphicsGroup @ p0, Text["A", Offset[-5, -5, 0, 0]],
          GraphicsGroup @ p1, Text["B", Offset[-5, -5, 2, 1]]
          , ImageSize -> 200, 100]


          enter image description here






          share|improve this answer









          $endgroup$








          • 2




            $begingroup$
            A formulation without Offset: Graphics[GraphicsGroup /@ p0, Text["A", 0, 0, 1, 1], p1, Text["B", 2, 1, -2, -1], ImageSize -> 200, 100]
            $endgroup$
            – Mr.Wizard
            Jul 10 at 15:23


















          4












          $begingroup$

          This is just a little remark. Using Kuba's answer above we can define a help function



          namedPoint[pt_, ptName_, ptSize_: Medium, offset__: -5, -5] := 
          Module[,
          GraphicsGroup[PointSize[ptSize], Point[pt],
          Text[ptName, Offset[offset, pt]]]
          ]


          and do simple calls like



          Graphics[namedPoint[0, 0, "O"], namedPoint[1, 1, "A"], 
          namedPoint[2, -1, "B"], ImageSize -> 100]


          which gives and image like this



          <code>enter image description here</code>






          share|improve this answer









          $endgroup$












          • $begingroup$
            The default arguments for ptSize and offset above are defined as "positional" argument using _: patterns. A better way would be to use optional arguments. Google "Setting Up Functions with Optional Arguments".
            $endgroup$
            – Bob Ueland
            Jul 11 at 8:52


















          4












          $begingroup$

          Another possibility is to use Callout inside of ListPlot:



          ListPlot[Callout[p0[[1]], "A"], Callout[p1[[1]],"B"]]


          enter image description here






          share|improve this answer









          $endgroup$












          • $begingroup$
            Callout is only available in Mathematica 11 and later.
            $endgroup$
            – Bob Ueland
            Jul 10 at 15:31










          • $begingroup$
            I am not 100% it was a requirement but you can't move the label and the point together.
            $endgroup$
            – Kuba
            Jul 11 at 8:12


















          0












          $begingroup$

          Recenter your coordinate system and rescale the text coordinates



          -1, -0.5, 1, .5 //
          Graphics[
          Point /@ #,
          Text[#1, .9 #2] &~MapThread~"A", "B", #
          ]&





          share|improve this answer









          $endgroup$















            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "387"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f201838%2fhow-do-you-glue-a-text-to-a-point%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            4 Answers
            4






            active

            oldest

            votes








            4 Answers
            4






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            8












            $begingroup$

            First of all your Offset specification is strange, I'd make it Offset[-5, -5, 2, 1], right?



            Then, you can use GraphicsGroup to treat it as a single item for the purpose of interactive editing:



            p0 = Point[0, 0];
            p1 = Point[2, 1];
            Graphics[
            GraphicsGroup @ p0, Text["A", Offset[-5, -5, 0, 0]],
            GraphicsGroup @ p1, Text["B", Offset[-5, -5, 2, 1]]
            , ImageSize -> 200, 100]


            enter image description here






            share|improve this answer









            $endgroup$








            • 2




              $begingroup$
              A formulation without Offset: Graphics[GraphicsGroup /@ p0, Text["A", 0, 0, 1, 1], p1, Text["B", 2, 1, -2, -1], ImageSize -> 200, 100]
              $endgroup$
              – Mr.Wizard
              Jul 10 at 15:23















            8












            $begingroup$

            First of all your Offset specification is strange, I'd make it Offset[-5, -5, 2, 1], right?



            Then, you can use GraphicsGroup to treat it as a single item for the purpose of interactive editing:



            p0 = Point[0, 0];
            p1 = Point[2, 1];
            Graphics[
            GraphicsGroup @ p0, Text["A", Offset[-5, -5, 0, 0]],
            GraphicsGroup @ p1, Text["B", Offset[-5, -5, 2, 1]]
            , ImageSize -> 200, 100]


            enter image description here






            share|improve this answer









            $endgroup$








            • 2




              $begingroup$
              A formulation without Offset: Graphics[GraphicsGroup /@ p0, Text["A", 0, 0, 1, 1], p1, Text["B", 2, 1, -2, -1], ImageSize -> 200, 100]
              $endgroup$
              – Mr.Wizard
              Jul 10 at 15:23













            8












            8








            8





            $begingroup$

            First of all your Offset specification is strange, I'd make it Offset[-5, -5, 2, 1], right?



            Then, you can use GraphicsGroup to treat it as a single item for the purpose of interactive editing:



            p0 = Point[0, 0];
            p1 = Point[2, 1];
            Graphics[
            GraphicsGroup @ p0, Text["A", Offset[-5, -5, 0, 0]],
            GraphicsGroup @ p1, Text["B", Offset[-5, -5, 2, 1]]
            , ImageSize -> 200, 100]


            enter image description here






            share|improve this answer









            $endgroup$



            First of all your Offset specification is strange, I'd make it Offset[-5, -5, 2, 1], right?



            Then, you can use GraphicsGroup to treat it as a single item for the purpose of interactive editing:



            p0 = Point[0, 0];
            p1 = Point[2, 1];
            Graphics[
            GraphicsGroup @ p0, Text["A", Offset[-5, -5, 0, 0]],
            GraphicsGroup @ p1, Text["B", Offset[-5, -5, 2, 1]]
            , ImageSize -> 200, 100]


            enter image description here







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jul 10 at 7:10









            KubaKuba

            110k12 gold badges217 silver badges555 bronze badges




            110k12 gold badges217 silver badges555 bronze badges







            • 2




              $begingroup$
              A formulation without Offset: Graphics[GraphicsGroup /@ p0, Text["A", 0, 0, 1, 1], p1, Text["B", 2, 1, -2, -1], ImageSize -> 200, 100]
              $endgroup$
              – Mr.Wizard
              Jul 10 at 15:23












            • 2




              $begingroup$
              A formulation without Offset: Graphics[GraphicsGroup /@ p0, Text["A", 0, 0, 1, 1], p1, Text["B", 2, 1, -2, -1], ImageSize -> 200, 100]
              $endgroup$
              – Mr.Wizard
              Jul 10 at 15:23







            2




            2




            $begingroup$
            A formulation without Offset: Graphics[GraphicsGroup /@ p0, Text["A", 0, 0, 1, 1], p1, Text["B", 2, 1, -2, -1], ImageSize -> 200, 100]
            $endgroup$
            – Mr.Wizard
            Jul 10 at 15:23




            $begingroup$
            A formulation without Offset: Graphics[GraphicsGroup /@ p0, Text["A", 0, 0, 1, 1], p1, Text["B", 2, 1, -2, -1], ImageSize -> 200, 100]
            $endgroup$
            – Mr.Wizard
            Jul 10 at 15:23













            4












            $begingroup$

            This is just a little remark. Using Kuba's answer above we can define a help function



            namedPoint[pt_, ptName_, ptSize_: Medium, offset__: -5, -5] := 
            Module[,
            GraphicsGroup[PointSize[ptSize], Point[pt],
            Text[ptName, Offset[offset, pt]]]
            ]


            and do simple calls like



            Graphics[namedPoint[0, 0, "O"], namedPoint[1, 1, "A"], 
            namedPoint[2, -1, "B"], ImageSize -> 100]


            which gives and image like this



            <code>enter image description here</code>






            share|improve this answer









            $endgroup$












            • $begingroup$
              The default arguments for ptSize and offset above are defined as "positional" argument using _: patterns. A better way would be to use optional arguments. Google "Setting Up Functions with Optional Arguments".
              $endgroup$
              – Bob Ueland
              Jul 11 at 8:52















            4












            $begingroup$

            This is just a little remark. Using Kuba's answer above we can define a help function



            namedPoint[pt_, ptName_, ptSize_: Medium, offset__: -5, -5] := 
            Module[,
            GraphicsGroup[PointSize[ptSize], Point[pt],
            Text[ptName, Offset[offset, pt]]]
            ]


            and do simple calls like



            Graphics[namedPoint[0, 0, "O"], namedPoint[1, 1, "A"], 
            namedPoint[2, -1, "B"], ImageSize -> 100]


            which gives and image like this



            <code>enter image description here</code>






            share|improve this answer









            $endgroup$












            • $begingroup$
              The default arguments for ptSize and offset above are defined as "positional" argument using _: patterns. A better way would be to use optional arguments. Google "Setting Up Functions with Optional Arguments".
              $endgroup$
              – Bob Ueland
              Jul 11 at 8:52













            4












            4








            4





            $begingroup$

            This is just a little remark. Using Kuba's answer above we can define a help function



            namedPoint[pt_, ptName_, ptSize_: Medium, offset__: -5, -5] := 
            Module[,
            GraphicsGroup[PointSize[ptSize], Point[pt],
            Text[ptName, Offset[offset, pt]]]
            ]


            and do simple calls like



            Graphics[namedPoint[0, 0, "O"], namedPoint[1, 1, "A"], 
            namedPoint[2, -1, "B"], ImageSize -> 100]


            which gives and image like this



            <code>enter image description here</code>






            share|improve this answer









            $endgroup$



            This is just a little remark. Using Kuba's answer above we can define a help function



            namedPoint[pt_, ptName_, ptSize_: Medium, offset__: -5, -5] := 
            Module[,
            GraphicsGroup[PointSize[ptSize], Point[pt],
            Text[ptName, Offset[offset, pt]]]
            ]


            and do simple calls like



            Graphics[namedPoint[0, 0, "O"], namedPoint[1, 1, "A"], 
            namedPoint[2, -1, "B"], ImageSize -> 100]


            which gives and image like this



            <code>enter image description here</code>







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jul 10 at 9:54









            Bob UelandBob Ueland

            5392 silver badges14 bronze badges




            5392 silver badges14 bronze badges











            • $begingroup$
              The default arguments for ptSize and offset above are defined as "positional" argument using _: patterns. A better way would be to use optional arguments. Google "Setting Up Functions with Optional Arguments".
              $endgroup$
              – Bob Ueland
              Jul 11 at 8:52
















            • $begingroup$
              The default arguments for ptSize and offset above are defined as "positional" argument using _: patterns. A better way would be to use optional arguments. Google "Setting Up Functions with Optional Arguments".
              $endgroup$
              – Bob Ueland
              Jul 11 at 8:52















            $begingroup$
            The default arguments for ptSize and offset above are defined as "positional" argument using _: patterns. A better way would be to use optional arguments. Google "Setting Up Functions with Optional Arguments".
            $endgroup$
            – Bob Ueland
            Jul 11 at 8:52




            $begingroup$
            The default arguments for ptSize and offset above are defined as "positional" argument using _: patterns. A better way would be to use optional arguments. Google "Setting Up Functions with Optional Arguments".
            $endgroup$
            – Bob Ueland
            Jul 11 at 8:52











            4












            $begingroup$

            Another possibility is to use Callout inside of ListPlot:



            ListPlot[Callout[p0[[1]], "A"], Callout[p1[[1]],"B"]]


            enter image description here






            share|improve this answer









            $endgroup$












            • $begingroup$
              Callout is only available in Mathematica 11 and later.
              $endgroup$
              – Bob Ueland
              Jul 10 at 15:31










            • $begingroup$
              I am not 100% it was a requirement but you can't move the label and the point together.
              $endgroup$
              – Kuba
              Jul 11 at 8:12















            4












            $begingroup$

            Another possibility is to use Callout inside of ListPlot:



            ListPlot[Callout[p0[[1]], "A"], Callout[p1[[1]],"B"]]


            enter image description here






            share|improve this answer









            $endgroup$












            • $begingroup$
              Callout is only available in Mathematica 11 and later.
              $endgroup$
              – Bob Ueland
              Jul 10 at 15:31










            • $begingroup$
              I am not 100% it was a requirement but you can't move the label and the point together.
              $endgroup$
              – Kuba
              Jul 11 at 8:12













            4












            4








            4





            $begingroup$

            Another possibility is to use Callout inside of ListPlot:



            ListPlot[Callout[p0[[1]], "A"], Callout[p1[[1]],"B"]]


            enter image description here






            share|improve this answer









            $endgroup$



            Another possibility is to use Callout inside of ListPlot:



            ListPlot[Callout[p0[[1]], "A"], Callout[p1[[1]],"B"]]


            enter image description here







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jul 10 at 14:34









            Carl WollCarl Woll

            87.6k3 gold badges115 silver badges224 bronze badges




            87.6k3 gold badges115 silver badges224 bronze badges











            • $begingroup$
              Callout is only available in Mathematica 11 and later.
              $endgroup$
              – Bob Ueland
              Jul 10 at 15:31










            • $begingroup$
              I am not 100% it was a requirement but you can't move the label and the point together.
              $endgroup$
              – Kuba
              Jul 11 at 8:12
















            • $begingroup$
              Callout is only available in Mathematica 11 and later.
              $endgroup$
              – Bob Ueland
              Jul 10 at 15:31










            • $begingroup$
              I am not 100% it was a requirement but you can't move the label and the point together.
              $endgroup$
              – Kuba
              Jul 11 at 8:12















            $begingroup$
            Callout is only available in Mathematica 11 and later.
            $endgroup$
            – Bob Ueland
            Jul 10 at 15:31




            $begingroup$
            Callout is only available in Mathematica 11 and later.
            $endgroup$
            – Bob Ueland
            Jul 10 at 15:31












            $begingroup$
            I am not 100% it was a requirement but you can't move the label and the point together.
            $endgroup$
            – Kuba
            Jul 11 at 8:12




            $begingroup$
            I am not 100% it was a requirement but you can't move the label and the point together.
            $endgroup$
            – Kuba
            Jul 11 at 8:12











            0












            $begingroup$

            Recenter your coordinate system and rescale the text coordinates



            -1, -0.5, 1, .5 //
            Graphics[
            Point /@ #,
            Text[#1, .9 #2] &~MapThread~"A", "B", #
            ]&





            share|improve this answer









            $endgroup$

















              0












              $begingroup$

              Recenter your coordinate system and rescale the text coordinates



              -1, -0.5, 1, .5 //
              Graphics[
              Point /@ #,
              Text[#1, .9 #2] &~MapThread~"A", "B", #
              ]&





              share|improve this answer









              $endgroup$















                0












                0








                0





                $begingroup$

                Recenter your coordinate system and rescale the text coordinates



                -1, -0.5, 1, .5 //
                Graphics[
                Point /@ #,
                Text[#1, .9 #2] &~MapThread~"A", "B", #
                ]&





                share|improve this answer









                $endgroup$



                Recenter your coordinate system and rescale the text coordinates



                -1, -0.5, 1, .5 //
                Graphics[
                Point /@ #,
                Text[#1, .9 #2] &~MapThread~"A", "B", #
                ]&






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jul 10 at 7:18









                FortsaintFortsaint

                8607 silver badges11 bronze badges




                8607 silver badges11 bronze badges



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Mathematica Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f201838%2fhow-do-you-glue-a-text-to-a-point%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Get product attribute by attribute group code in magento 2get product attribute by product attribute group in magento 2Magento 2 Log Bundle Product Data in List Page?How to get all product attribute of a attribute group of Default attribute set?Magento 2.1 Create a filter in the product grid by new attributeMagento 2 : Get Product Attribute values By GroupMagento 2 How to get all existing values for one attributeMagento 2 get custom attribute of a single product inside a pluginMagento 2.3 How to get all the Multi Source Inventory (MSI) locations collection in custom module?Magento2: how to develop rest API to get new productsGet product attribute by attribute group code ( [attribute_group_code] ) in magento 2

                    Category:9 (number) SubcategoriesMedia in category "9 (number)"Navigation menuUpload mediaGND ID: 4485639-8Library of Congress authority ID: sh85091979ReasonatorScholiaStatistics

                    Magento 2.3: How do i solve this, Not registered handle, on custom form?How can i rewrite TierPrice Block in Magento2magento 2 captcha not rendering if I override layout xmlmain.CRITICAL: Plugin class doesn't existMagento 2 : Problem while adding custom button order view page?Magento 2.2.5: Overriding Admin Controller sales/orderMagento 2.2.5: Add, Update and Delete existing products Custom OptionsMagento 2.3 : File Upload issue in UI Component FormMagento2 Not registered handleHow to configured Form Builder Js in my custom magento 2.3.0 module?Magento 2.3. How to create image upload field in an admin form