Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

DOC: re-add api example#26624

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
jklymak wants to merge1 commit intomatplotlib:mainfromjklymak:doc-re-example-api

Conversation

jklymak
Copy link
Member

PR summary

This re-introduces the example inapi/index, and adds a pyplot counterexample.

As discussed in#26623 - this provides concrete examples of the abstract concepts being discussed and makes the API pages more self-contained.

PR checklist

@story645
Copy link
Member

I don't think self-contained should be a goal b/c that's how we end up w/ example drift and scope creep. I think as much as possible we should be cross linking to one source of truth cause that's more maintainable and makes things more discoverable.

Copy link
Member

@story645story645 left a comment
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think the example as given is cluttered in a way that obfuscates the goal of trying to highlight the API differences. I also think that since this is a doc regression it should have two approvals.

ETA: I also very much appreciate that you put the example into the pyplot and axes explanations.

Comment on lines +46 to +56
x = np.arange(0, 4, 0.05)
y = np.sin(x*np.pi)
# Create a Figure and an Axes:
fig, ax = plt.subplots(figsize=(3,2), layout='constrained')
# Use the Axes to plot and label:
ax.plot(x, y)
ax.set_xlabel('t [s]')
ax.set_ylabel('S [V]')
ax.set_title('Sine wave')
# Change a property of the Figure:
fig.set_facecolor('lightsteelblue')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
x = np.arange(0, 4, 0.05)
y = np.sin(x*np.pi)
# Create a Figure and an Axes:
fig, ax = plt.subplots(figsize=(3,2), layout='constrained')
# Use the Axes to plot and label:
ax.plot(x, y)
ax.set_xlabel('t [s]')
ax.set_ylabel('S [V]')
ax.set_title('Sine wave')
# Change a property of the Figure:
fig.set_facecolor('lightsteelblue')
# Create a Figure and an Axes:
fig, ax = plt.subplots(figsize=(3,2), layout='constrained')
# add a plot to the Axes ax
ax.plot(np.sin(np.linspace(0, 2*np.pi))
# label the Axes and x and y Axis
ax.set(xlabel= 't [s]', ylabel = 'S [V]', title ='Sine wave')
# Change the face color of the Figure:
fig.set_facecolor('lightsteelblue')

I think the original is a bit too long and also I think we want to encourage set unless they need the individual properties

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ax.set is pretty obscure as a way to shorten things.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

But I think we want folks to know about it. I also agree w/ Tim that this should be as short as possible, and probably in a 2 column grid rather than tabs 'cause it's that side by side that really illustrates the difference.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Two column is fine, though it looks pretty cramped.

Reax.set that seems an advanced usage to me, whereas I thought we wanted this to be straightforward? ax.,set also does not allow one to customize anything in the set methods (eg fontsize in title etc), so I'm not sure it should become canonical usage.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Out of scope here but I think that's a point we're trying to make in all sorts of places - that if you don't need customization we've got this nice method that will do all the things at once, but if you need customization then you've gotta use the specific methods to do so cause we try to scope our functions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

There is a lot of value in the 1:1 mapping between the lines so am very 👎🏻 on changing to useax.set.

At least for me clicking between the tabs and seeing what does/does not change is way easier to see the differences than trying to scan between two columns.

@jklymak
Copy link
MemberAuthor

jklymak commentedAug 29, 2023
edited
Loading

I also think that since this is a doc regression it should have two approvals.

The example originally came in#19727. It was removed in#26402 without mention of the removal in the PR description, or discussion, on the strength of one review. I'm not clear how re-instating it is considered a regression.

@story645
Copy link
Member

I'm not clear how re-instating it is considered a regression

B/c it was removed and now it's going back? I think if we're thrashing back and forth then it's worth slowing down and giving space for at least one other person to sign off. In this case in particular I think it'd be good if@timhoffm at least saw this PR.

@timhoffm
Copy link
Member

timhoffm commentedAug 30, 2023
edited
Loading

The example originally came in#19727. It was removed in#26402 without mention of the removal in the PR description, or discussion

In#26402, I motivated the change:

Reduce the interface description to very compact two-sentence descriptions and refer to the interface page for everything else.

The focus here is to point the users to relevant API resources for the respective interfaces, not to discuss these interfaces in detail. The latter is the task ofhttps://matplotlib.org/devdocs/users/explain/figure/api_interfaces.html

This page is the entry point for theAPI reference, the collection of all function / class docstrings. Categorizing according tohttps://documentation.divio.com/ it is information-oriented, not learning-oriented or explanation-oriented.

My train of thought for deciding on the contents of the page is:

  1. In the very basic form, theModules section would be enough.

  2. However, the user-facing interfaces are what people will need most of the time. Prominently highlighting then in the boxes directs the user to the most relevant content:

    grafik

  3. For people who already know the interfaces, this would be enough. But we know that a lot of users have no clear idea on this. To help them decide between the worlds, we sould give a very rough idea and link to the detailed description if they want to /need to learn more. - But this additional interface description should be as terse as possible because it distracts from the actual relevant links in 2. and 1.

In particular, I believe a visual plot would be harming the cause here. It draws a lot of visual attention and does not explain anything about the API or Interfaces. I would be +/-0 on adding minimal pure code-blocks to the existing interface cards

fig, ax = plt.subplots()ax.plot(x, y)ax.set_title('Sample plot')plt.show()
plt.plot(x, y)plt.title('Sample plot')plt.show()

On a general note, the major issue with our documentation is not that it's missing content or explanations. It's structure and guidance that is lacking. IMHO we gain a lot if we focus pages on their primary purpose and strip / link other aspects.

story645 and paniterka reacted with thumbs up emoji

@jklymak
Copy link
MemberAuthor

jklymak commentedAug 30, 2023
edited
Loading

I believe a visual plot would be harming the cause here. It draws a lot of visual attention and does not explain anything about the API or Interfaces

I strongly feel the example helps set the context for what is being discussed on this page. Our API is very bizarre in that 95% of it is on the Axes objects we create, and showing a short example of that on a top-level landing page helps orient the reader.

Categorizing according tohttps://documentation.divio.com/ it is information-oriented, not learning-oriented or explanation-oriented.

Divio is a nice way to think about the purposes of documentation, but I don't think it is a rational way to organize things with pristine separation of the types of information. Information doesn't mean anything without some context.

For others who do not wish to click through:

@timhoffm
Copy link
Member

Information doesn't mean anything without some context.

Fully agree and that's why I added bullet point 3. in my reasoning. The key here issome. Can we agree on the principle thatsome means "enough to help understanding the main information, but as little as possible to not distract from the main information"? - The judgement call, and where I think we disargee is, is what is "enough".

I strongly feel the example helps set the context for what is being discussed on this page. Our API is very bizarre in that 95% of it is on the Axes objects we create, and showing a short example of that on a top-level landing page helps orient the reader.

For the context, the priority, determined by relevance, is:

  1. Short fundamental description: we agree on this
  2. Code snippet to illustrate how the API looks: as written above, I'm +/-0 on this - I don't think it's essential, but it's compact enough to not distract.
  3. Resulting plot of the code example: The visual plot does not really help in understanding the API. I propose that
    plt.plot(x, y)plt.title('Sample plot')plt.show()
    is self-explanatory enough. An added problem of the visual is that you have to provide fully working code, which means you have to clutter the code with import and data generation, which clearly do not add to understanding the API.
    IMHO this is too much clutter for almost no gain.

@jklymak
Copy link
MemberAuthor

I think it is a strange aesthetic to just show the code, but not show the code result in a plotting library. Code tends to be a lot easier to parse if you can see its result. You say it's "cluttered", and "distracts". But from what? There is no other content on this page - the rest of this page is just an index (that is repeated verbatim on the left sidebar).

@story645
Copy link
Member

You say it's "cluttered", and "distracts". But from what?

I mean that there's a lot ofcognitive overload happening. Your example demonstrates data creation, figure and axes creation, plotting, labeling, and fig saving - and yes that's all very useful and things folks always want to do, but the question is are those concepts we want to be demoing here? Especially for a user who does not know the API, they may get disctracted by creation->plot->label and not focus on the difference between pyplot and axes which is what we want to be highlighting.

timhoffm reacted with thumbs up emoji

@timhoffm
Copy link
Member

I think it is a strange aesthetic to just show the code, but not show the code result in a plotting library.

It depends on what you want to achieve with that code. There are lots ofExamples sections in our docstrings that do not generate the plot.

story645 reacted with thumbs up emoji

ax.plot(x, y)
ax.set_xlabel('t [s]')
ax.set_ylabel('S [V]')
ax.set_title('Sine wave')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
ax.set_title('Sine wave')
ax.set_title('Sine wave (explicit)')

plt.plot(x, y)
plt.xlabel('t [s]')
plt.ylabel('S [V]')
plt.title('Sine wave')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
plt.title('Sine wave')
plt.title('Sine wave (implicit)')

@story645
Copy link
Member

Since#26671 is merged, should this PR be closed? Because merging this PR would undo the work in#26671 that was proposed as an alternative to this PR.

@jklymak
Copy link
MemberAuthor

The point of this PR was to re-add the figure.#26671 did not re-add the figure, and obviously there is some disagreement about whether figures are desirable in our docs.

@story645story645 added the status: needs comment/discussionneeds consensus on next step labelSep 20, 2023
@story645
Copy link
Member

and obviously there is some disagreement about whether figures are desirable in our docs.

The disagreement is about whether a figure in this specific document clarifies or obfuscates the intended takeaway from the document, which is why#26671 added code to highlight the differences instead of a figure.

I think at this point we probably need to have a full discussion cause otherwise we'll end up w/ more add-remove cycles, so I'm gonna put up a block until that happens.

Copy link
Member

@story645story645 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'm wary of an add-remove-add-remove cycle happening, so blocking until broader consensus is achieved.

@tacaswell
Copy link
Member

I think the longer example with an image is actually quite helpful here, particularly as written with the 1:1 mapping of the lines of code. By flipping back and forth between the tabs it is easy to see what the required changes are and than you get the same output either way (the only change I would suggest would be to make the titles different so it is clear that the imageis changing between the tabs, currently the only way to tell is to mouse over them and see the urls are different).

We (the developers) know that the APIs are interchangeable, but that may not be clear to all of our users so showing that you can get exactly the same output using either path is a good thing. It is also good to show that the explicit API is not also necessarily more verbose.


We probably should re-write some of the examples inhttps://matplotlib.org/devdocs/users/explain/figure/api_interfaces.html using this 2 tab style.

@story645
Copy link
Member

By flipping back and forth between the tabs it is easy to see what the required changes are

Having to flip back and forth between tabs to see the difference itself obfuscates the difference because it requires the learner to hold the not visible code in memory while looking at the visible one - and that's a lot of cognitive overload for someone who may not know what they're supposed to be holding in their head while flipping between the tabs.

I love tabs and think they're fantastic for presenting mutually exclusive - you can either do this thing or that thing and not both - information. But I don't think the goal on this page is necessarily to get folks to pick one - my guess is they'll go w/ the one they know cause that's easiest - but to see both so they can compare. And tables are better for comparison. Here's one example of universal design folks talking about tabs for reading flow controlsuniversaldesign.ie

@tacaswell
Copy link
Member

tabs

At least to my eye the tabs really highlight exactly what is changing between the two and widely spaced (or vertically stacked) code blocks are much much harder to compare.

@story645
Copy link
Member

and widely spaced (or vertically stacked) code blocks are much much harder to compare.

Yes, which is why in the current iteration of the page there are only 3 lines of code: it's condensed enough to fit on a phone screen:Screenshot_20230921-115113.png

@timhoffm
Copy link
Member

timhoffm commentedSep 22, 2023
edited
Loading

My major concerns:

  • The example code is too complex. One can see 90% of the difference in a 3-4 line example as well.
    This should only be a very high-level overview. We link tothe detailed interface description, which discusses all the details.
  • Back and forth switching is cumbersome, and people have to understand that they should do it to see the difference.

I still find the current side-by-side solution really concise:

image

I don't think the rendered figure is relevant, but if you consider it valuable, I suggest to make a full-width div below the two columns:

Both example codes yield the same figure:

[rendered figure]

@jklymak
Copy link
MemberAuthor

jklymak commentedSep 22, 2023
edited
Loading

At the end of the day, these are all taste issues. I think the final documentation say is@tacaswell, so he should just state his preference.

I will point out some usability issues with the current links - I think thatFigure should be changed back tomatplotlib.figure because the first links to the init docshttps://matplotlib.org/stable/api/figure_api.html#matplotlib.figure.Figure which no one ever uses, and the latter links to the top of the API page, which has the TOC for Figure methods that peopledo use. Same forAxes/matplotlib.axes.

@story645
Copy link
Member

story645 commentedSep 24, 2023
edited
Loading

At the end of the day, these are all taste issues

I think they're best practices issues.

  • tabs are best suited for mutually exclusive (pip or conda) or sequential (stage 1, stage 2, etc) information.
    On the other hand generally it's much easier to compare information when it is side by side- consider a paper where figure A and B need to be compared and whether you'd place them right next to each other as subbplots or place figure B six pages away from figure A.

  • too much information starts obfuscating what's trying to be communicated and leads to worse retention - what's the minimum folks need to hold in their head to see that the APIs differ. We have other pages in the docs where we show all the things, how does doing that here help to more effectively communicate the differences between the two APIs?

I think@timhoffm's suggestion of putting one figure at the buttom of the grid showing that both code blocks produce the same visual is a good compromise in terms of having a visual.

timhoffm reacted with thumbs up emoji

@jklymak
Copy link
MemberAuthor

Again, whether something looks better tabbed or side-by-side is not subject to any hard and fast rules. FWIW I prefer side-by-side, but I wouldn't claim that my preference is "right" or a "best-practice". I had a slight preference for tabbed here just because it was more compact.

We have other pages in the docs where we show all the things, how does doing that here help to more effectively communicate the differences between the two APIs?

The original impetus to improving this page (#19727), and adding an example, is that this is the top-level API landing page, arrived at via "Reference". Lots of people who think they are familiar with Matplotlib probably land on "Reference", and then don't know where to go. I distinctly remember getting started with our API, and not understanding that most of it was in theAxes class. So while Iknew that there was such a thing asax.plot I did not know where to find its documentation, other thanpyplot.plot, which is not quite the same thing.

In my mind, the goal of these improvements wasnot primarily to "communicate the difference between the two APIs". Indeed the original version of this had all the different API discussionbelow the TOC (https://matplotlib.org/3.5.3/api/index.html). Rather the goal was to provide a quick guide/reminder of our API using code snippets, and their results, that user may have seen elsewhere, be that in our docs, stack overflow etc. I agree that the difference between the APIs needs to be communicated, but as a small part of the larger goal of providing a guide the API reference.

@story645
Copy link
Member

story645 commentedSep 24, 2023
edited
Loading

FWIW I prefer side-by-side

Why do you prefer it? And do you think the users reading this page may prefer it for the same reasons?

The choice of tabs or tables creates different reading/learning experiences for comparing A and B:

  • A and B next to each other
  • flipping back and forth between A and B

but I wouldn't claim that my preference is "right" or a "best-practice".

but as a small part of the larger goal of providing a guide the API reference.

How does adding data generation and a few more set methods do that? I mean this in earnest, as the current code on the page shows the three major components of making a graph that Matplotlib is in charge of:

  1. setup drawing area
  2. draw plot
  3. label things

I especially worry about including data creation b/c we already have enough trouble getting folks to realize that Matplotlib is just the graphs part, and I don't think putting Numpy on our API reference page will help.

This is also making me think that what may be a better way to improve that page would be to put modules in alphabetical order in a tab/different page and reorganize the modules list so that is instead grouped into some reasonable categories so folks who do not know what we call things could still navigate to the right modules. Something like:

timhoffm reacted with thumbs up emoji

@jklymak
Copy link
MemberAuthor

The data creation is pretty trivial - I hope we can assume our readers have basic familiarity with numpy. Further, it makes it clear what kind of objects x and y are, versus completely unspecified.

As for the setters, I think labelling a plot is best practice and common enough to warrant a couple of lines here.

As for tabs versus side by side, in addition to size issues, we are trying to discourage one of the APIs - recall the original version didn't even have the pyplot API example. In fact for the purpose of indexing I'm not even sure it's needed at all since the pyplot API is easy to find

I wouldn't object to re organizing the API on the page, but that is somewhat orthogonal here

@story645
Copy link
Member

story645 commentedSep 24, 2023
edited
Loading

The data creation is pretty trivial - I hope we can assume our readers have basic familiarity with numpy.

They may, but also may not realize that it's not built into Matplotlib. (ETA: bootcamp curricula in particular have an unfortunate tendency to lump the libraries together).

Further, it makes it clear what kind of objects x and y are, versus completely unspecified.

But isn't the point here that.plot(x,y) will work on almost any type of x,y? and also I think of this code as almost template code (basic usage pattern is what you called it in#26623) -> [create]->[visualize]->[label]
with the goal being that finding one of the creation functions or plot functions or labeling functions will find the whole batch of 'em?

, we are trying to discourage one of the APIs - recall the original version didn't even have the pyplot API example. In fact for the purpose of indexing I'm not even sure it's needed at all since the pyplot API is easy to find

this table exists to orient users to what we mean by API/OO/explicit vs pyplot/implicit API -> this is the back and forth in#26623 - so that they can find the right module. If they need usage guidance, they should be directed to the user guide where all this stuff is explained. Granted, I dunno that I'd be opposed to putting everything in tabs (so each column of the table gets integrated into a tab) but my guess is that the folks who most need the definitions would also benefit most from seeing them side by side.

As for the setters, I think labelling a plot is best practice and common enough to warrant a couple of lines here.

100% agree it's best practice, but this page isn't supposed to be a "how to use matplotlib" page.

@jklymak
Copy link
MemberAuthor

Again, we disagree fundamentally on most of these points, none of which have an objective criteria. Someone, presumably@tacaswell, will have to decide what they want this page to look like.

@story645
Copy link
Member

Someone, presumably@tacaswell, will have to decide what they want this page to look like.

Or the API docs lead, who is@timhoffm

@jklymak
Copy link
MemberAuthor

Sure, if that falls under that bailiwick, I'll close this.

@jklymakjklymak deleted the doc-re-example-api branchSeptember 25, 2023 00:44
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@tacaswelltacaswelltacaswell left review comments

@story645story645story645 requested changes

Assignees
No one assigned
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

4 participants
@jklymak@story645@timhoffm@tacaswell

[8]ページ先頭

©2009-2025 Movatter.jp