10000 Merge branch 'main' of https://github.com/matplotlib/matplotlib into … · matplotlib/matplotlib@af03a7d · GitHub
[go: up one dir, main page]

Skip to content

Commit af03a7d

Browse files
committed
Merge branch 'main' of https://github.com/matplotlib/matplotlib into repr-html-fonts
2 parents 171d8d5 + 0fc7c4b commit af03a7d

File tree

15 files changed

+231
-132
lines changed

15 files changed

+231
-132
lines changed

.github/workflows/pr_welcome.yml

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,29 @@ jobs:
77
runs-on: ubuntu-latest
88

99
steps:
10-
- uses: actions/first-interaction@v1
11-
with:
12-
add-labels: "status: needs workflow approval"
13-
repo-token: ${{ secrets.GITHUB_TOKEN }}
14-
pr-message: >+
15-
Thank you for opening your first PR into Matplotlib!
10+
- uses: actions/first-interaction@v1
11+
with:
12+
repo-token: ${{ secrets.GITHUB_TOKEN }}
13+
pr-message: >+
14+
Thank you for opening your first PR into Matplotlib!
1615
1716
18-
If you have not heard from us in a while, please feel free to
19-
ping `@matplotlib/developers` or anyone who has commented on the
20-
PR. Most of our reviewers are volunteers and sometimes
21-
things fall through the cracks.
17+
If you have not heard from us in a while, please feel free to ping
18+
`@matplotlib/developers` or anyone who has commented on the PR.
19+
Most of our reviewers are volunteers and sometimes things fall
20+
through the cracks.
2221
2322
24-
You can also join us [on
25-
gitter](https://gitter.im/matplotlib/matplotlib) for real-time
26-
discussion.
23+
You can also join us [on
24+
gitter](https://gitter.im/matplotlib/matplotlib) for real-time
25+
discussion.
2726
2827
29-
For details on testing, writing docs, and our review process,
30-
please see [the developer
31-
guide](https://matplotlib.org/devdocs/devel/index.html)
28+
For details on testing, writing docs, and our review process,
29+
please see [the developer
30+
guide](https://matplotlib.org/devdocs/devel/index.html)
3231
3332
34-
We strive to be a welcoming and open project. Please follow our
35-
[Code of
36-
Conduct](https://github.com/matplotlib/matplotlib/blob/main/CODE_OF_CONDUCT.md).
33+
We strive to be a welcoming and open project. Please follow our
34+
[Code of
35+
Conduct](https://github.com/matplotlib/matplotlib/blob/main/CODE_OF_CONDUCT.md).

examples/showcase/anatomy.py

Lines changed: 74 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,29 @@
66
This figure shows the name of several matplotlib elements composing a figure
77
"""
88

9+
910
import numpy as np
1011
import matplotlib.pyplot as plt
12+
from matplotlib.patches import Circle, Rectangle
13+
from matplotlib.patheffects import withStroke
1114
from matplotlib.ticker import AutoMinorLocator, MultipleLocator
1215

16+
royal_blue = "#002082"
17+
royal_blue = [0, 20/256, 82/256]
18+
19+
# make the figure
20+
1321
np.random.seed(19680801)
1422

1523
X = np.linspace(0.5, 3.5, 100)
1624
Y1 = 3+np.cos(X)
1725
Y2 = 1+np.cos(1+X/0.75)/2
1826
Y3 = np.random.uniform(Y1, Y2, len(X))
1927

20-
fig = plt.figure(figsize=(8, 8))
21-
ax = fig.add_subplot(1, 1, 1, aspect=1)
28+
fig = plt.figure(figsize=(8, 8), facecolor='1')
29+
marg = 0.15
30+
ax = fig.add_axes([marg, marg, 1-1.8*marg, 1-1.8*marg], aspect=1,
31+
facecolor='1')
2232

2333

2434
def minor_tick(x, pos):
@@ -36,110 +46,107 @@ def minor_tick(x, pos):
3646
ax.set_xlim(0, 4)
3747
ax.set_ylim(0, 4)
3848

39-
ax.tick_params(which='major', width=1.0)
40-
ax.tick_params(which='major', length=10)
49+
ax.tick_params(which='major', width=1.0, labelsize=14)
50+
ax.tick_params(which='major', length=10, labelsize=14)
4151
ax.tick_params(which='minor', width=1.0, labelsize=10)
4252
ax.tick_params(which='minor', length=5, labelsize=10, labelcolor='0.25')
4353

4454
ax.grid(linestyle="--", linewidth=0.5, color='.25', zorder=-10)
4555

46-
ax.plot(X, Y1, c=(0.25, 0.25, 1.00), lw=2, label="Blue signal", zorder=10)
47-
ax.plot(X, Y2, c=(1.00, 0.25, 0.25), lw=2, label="Red signal")
48-
ax.plot(X, Y3, linewidth=0,
49-
marker='o', markerfacecolor='w', markeredgecolor='k')
56+
ax.plot(X, Y1, c='C0', lw=2.5, label="Blue signal", zorder=10)
57+
ax.plot(X, Y2, c='C1', lw=2.5, label="Orange signal")
58+
ax.plot(X[::3], Y3[::3], linewidth=0, markersize=9,
59+
marker='s', markerfacecolor='none', markeredgecolor='C4',
60+
markeredgewidth=2.5)
5061

5162
ax.set_title("Anatomy of a figure", fontsize=20, verticalalignment='bottom')
52-
ax.set_xlabel("X axis label")
53-
ax.set_ylabel("Y axis label")
63+
ax.set_xlabel("x Axis label", fontsize=14)
64+
ax.set_ylabel("y Axis label", fontsize=14)
65+
66+
ax.legend(loc="upper right", fontsize=14)
5467

55-
ax.legend(loc="upper right")
68+
# Annotate the figure
5669

5770

58-
def circle(x, y, radius=0.15):
59-
from matplotlib.patches import Circle
60-
from matplotlib.patheffects import withStroke
61-
circle = Circle((x, y), radius, clip_on=False, zorder=10, linewidth=1,
62-
edgecolor='black', facecolor=(0, 0, 0, .0125),
63-
path_effects=[withStroke(linewidth=5, foreground='w')])
64-
ax.add_artist(circle)
71+
def just_circle(x, y, radius=0.15):
72+
c = Circle((x, y), radius, clip_on=False, zorder=10, linewidth=2.5,
73+
edgecolor=royal_blue + [0.6], facecolor='none',
74+
path_effects=[withStroke(linewidth=7, foreground=(1, 1, 1, 1))])
75+
ax.add_artist(c)
6576

6677

6778
def text(x, y, text):
68-
ax.text(x, y, text, backgroundcolor="white",
69-
ha='center', va='top', weight='bold', color='blue')
79+
ax.text(x, y, text, zorder=100,
80+
ha='center', va='top', weight='bold', color=royal_blue,
81+
style='italic', fontfamily='monospace',
82+
path_effects=[withStroke(linewidth=7, foreground=(1, 1, 1, 1))])
7083

7184

72-
# Minor tick
73-
circle(0.50, -0.10)
74-
text(0.50, -0.32, "Minor tick label")
85+
def code(x, y, text):
86+
ax.text(x, y, text, zorder=100,
87+
ha='center', va='top', weight='normal', color='0.0',
88+
fontfamily='Courier New', fontsize='medium',
89+
path_effects=[withStroke(linewidth=7, foreground=(1, 1, 1, 1))])
90+
91+
92+
def circle(x, y, txt, cde, radius=0.15):
93+
just_circle(x, y, radius=radius)
94+
text(x, y-0.2, txt)
95+
code(x, y-0.33, cde)
96+
97+
# Minor tick label
98+
circle(3.25, -0.10, "Minor tick label",
99+
"ax.xaxis.set_minor_formatter")
75100

76101
# Major tick
77-
circle(-0.03, 4.00)
78-
text(0.03, 3.80, "Major tick")
102+
circle(-0.03, 1.05, "Major tick", "ax.yaxis.set_major_locator")
79103

80104
# Minor tick
81-
circle(0.00, 3.50)
82-
text(0.00, 3.30, "Minor tick")
105+
y = 3.75
106+
circle(0.00, 3.75, "Minor tick", "ax.yaxis.set_minor_locator")
83107

84108
# Major tick label
85-
circle(-0.15, 3.00)
86-
text(-0.15, 2.80, "Major tick label")
109+
circle(-0.15, 3.00, "Major tick label", "ax.yaxis.set_major_formatter")
87110

88111
# X Label
89-
circle(1.80, -0.27)
90-
text(1.80, -0.45, "X axis label")
112+
circle(1.90, -0.32, "xlabel", "ax.set_xlabel")
91113

92114
# Y Label
93-
circle(-0.27, 1.80)
94-
text(-0.27, 1.6, "Y axis label")
115+
circle(-0.27, 1.68, "ylabel", "ax.set_ylabel")
95116

96117
# Title
97-
circle(1.60, 4.13)
98-
text(1.60, 3.93, "Title")
118+
circle(1.58, 4.13, "Title", "ax.set_title")
99119

100120
# Blue plot
101-
circle(1.75, 2.80)
102-
text(1.75, 2.60, "Line\n(line plot)")
103-
104-
# Red plot
105-
circle(1.20, 0.60)
106-
text(1.20, 0.40, "Line\n(line plot)")
121+
circle(1.75, 2.80, "Line", "ax.plot")
107122

108123
# Scatter plot
109-
circle(3.20, 1.75)
110-
text(3.20, 1.55, "Markers\n(scatter plot)")
124+
circle(2.25, 1.54, "Markers", "ax.scatter")
111125

112126
# Grid
113-
circle(3.00, 3.00)
114-
text(3.00, 2.80, "Grid")
127+
circle(3.00, 3.00, "Grid", "ax.grid")
115128

116129
# Legend
117-
circle(3.70, 3.80)
118-
text(3.70, 3.60, "Legend")
130+
circle(3.60, 3.65, "Legend", "ax.legend")
119131

120132
# Axes
121-
circle(0.5, 0.5)
122-
text(0.5, 0.3, "Axes")
133+
circle(2.5, 0.55, "Axes", "fig.subplots")
123134

124135
# Figure
125-
circle(-0.3, 0.65)
126-
text(-0.3, 0.45, "Figure")
127-
128-
color = 'blue'
129-
ax.annotate('Spines', xy=(4.0, 0.35), xytext=(3.3, 0.5),
130-
weight='bold', color=color,
131-
arrowprops=dict(arrowstyle='->',
132-
connectionstyle="arc3",
133-
color=color))
134-
135-
ax.annotate('', xy=(3.15, 0.0), xytext=(3.45, 0.45),
136-
weight='bold', color=color,
137-
arrowprops=dict(arrowstyle='->',
138-
connectionstyle="arc3",
139-
color=color))
140-
141-
ax.text(4.0, -0.4, "Made with https://matplotlib.org",
142-
fontsize=10, ha="right", color='.5')
136+
circle(4.185, 4.3, "Figure", "plt.figure")
137+
138+
# x Axis
139+
circle(0.65, 0.01, "x Axis", "ax.xaxis")
140+
141+
# y Axis
142+
circle(0, 0.44, "y Axis", "ax.yaxis")
143+
144+
# Spine
145+
circle(4.0, 0.7, "Spine", "ax.spines")
146+
147+
# frame around figure...
148+
fig.add_artist(Rectangle((0, 0), width=1, height=1, facecolor='none',
149+
edgecolor='0.5', linewidth=10))
143150

144151
plt.show()
145152

lib/matplotlib/axes/_base.py

Lines changed: 20 additions & 12 deletions
3493
Original file line numberDiff line numberDiff line change
@@ -3487,15 +3487,19 @@ def set_xlabel(self, xlabel, fontdict=None, labelpad=None, *,
34873487
f"its corresponding low level keyword "
34883488
f"arguments ({protected_kw}) are also "
34893489
f"supplied")
3490-
loc = 'center'
3490+
34913491
else:
34923492
loc = (loc if loc is not None
3493
else mpl.rcParams['xaxis.labellocation'])
3494-
_api.check_in_list(('left', 'center', 'right'), loc=loc)
3495-
if loc == 'left':
3496-
kwargs.update(x=0, horizontalalignment='left')
3497-
elif loc == 'right':
3498-
kwargs.update(x=1, horizontalalignment='right')
3494+
_api.check_in_list(('left', 'center', 'right'), loc=loc)
3495+
3496+
if loc == 'left':
3497+
kwargs.update(x=0, horizontalalignment='left')
3498+
elif loc == 'center':
3499+
kwargs.update(x=0.5, horizontalalignment='center')
3500+
elif loc == 'right':
3501+
kwargs.update(x=1, horizontalalignment='right')
3502+
34993503
return self.xaxis.set_label_text(xlabel, fontdict, **kwargs)
35003504

35013505
def invert_xaxis(self):
@@ -3831,15 +3835,19 @@ def set_ylabel(self, ylabel, fontdict=None, labelpad=None, *,
38313835
f"its corresponding low level keyword "
38323836
f"arguments ({protected_kw}) are also "
38333837
f"supplied")
3834-
loc = 'center'
3838+
38353839
else:
38363840
loc = (loc if loc is not None
38373841
else mpl.rcParams['yaxis.labellocation'])
3838-
_api.check_in_list(('bottom', 'center', 'top'), loc=loc)
3839-
if loc == 'bottom':
3840-
kwargs.update(y=0, horizontalalignment='left')
3841-
elif loc == 'top':
3842-
kwargs.update(y=1, horizontalalignment='right')
3842+
_api.check_in_list(('bottom', 'center', 'top'), loc=loc)
3843+
3844+
if loc == 'bottom':
3845+
kwargs.update(y=0, horizontalalignment='left')
3846+
elif loc == 'center':
3847+
kwargs.update(y=0.5, horizontalalignment='center')
3848+
elif loc == 'top':
3849+
kwargs.update(y=1, horizontalalignment='right')
3850+
38433851
return self.yaxis.set_label_text(ylabel, fontdict, **kwargs)
38443852

38453853
def invert_yaxis(self):

lib/matplotlib/backends/backend_macosx.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class FigureManagerMac(_macosx.FigureManager, FigureManagerBase):
6767
"""
6868
def __init__(self, canvas, num):
6969
_macosx.FigureManager.__init__(self, canvas)
70+
icon_path = str(cbook._get_data_path('images/matplotlib.pdf'))
71+
_macosx.FigureManager.set_icon(icon_path)
7072
FigureManagerBase.__init__(self, canvas, num)
7173
if mpl.rcParams['toolbar'] == 'toolbar2':
7274
self.toolbar = NavigationToolbar2Mac(canvas)

lib/matplotlib/colorbar.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,8 @@ def _process_values(self):
11011101
elif isinstance(self.norm, colors.NoNorm):
11021102
# NoNorm has N blocks, so N+1 boundaries, centered on integers:
11031103
b = np.arange(self.cmap.N + 1) - .5
1104+
elif self.boundaries is not None:
1105+
b = self.boundaries
11041106
else:
11051107
# otherwise make the boundaries from the size of the cmap:
11061108
N = self.cmap.N + 1
@@ -1117,7 +1119,8 @@ def _process_values(self):
11171119
self.norm.vmax = 1
11181120
self.norm.vmin, self.norm.vmax = mtransforms.nonsingular(
11191121
self.norm.vmin, self.norm.vmax, expander=0.1)
1120-
if not isinstance(self.norm, colors.BoundaryNorm):
1122+
if (not isinstance(self.norm, colors.BoundaryNorm) and
1123+
(self.boundaries is None)):
11211124
b = self.norm.inverse(b)
11221125

11231126
self._boundaries = np.asarray(b, dtype=float)
@@ -1141,7 +1144,8 @@ def _mesh(self):
11411144
norm.vmax = self.vmax
11421145
y, extendlen = self._proportional_y()
11431146
# invert:
1144-
if isinstance(< 9465 span class=pl-s1>norm, (colors.BoundaryNorm, colors.NoNorm)):
1147+
if (isinstance(norm, (colors.BoundaryNorm, colors.NoNorm)) or
1148+
self.boundaries is not None):
11451149
y = y * (self.vmax - self.vmin) + self.vmin # not using a norm.
11461150
else:
11471151
y = norm.inverse(y)
@@ -1237,7 +1241,8 @@ def _proportional_y(self):
12371241
Return colorbar data coordinates for the boundaries of
12381242
a proportional colorbar, plus extension lengths if required:
12391243
"""
1240-
if isinstance(self.norm, colors.BoundaryNorm):
1244+
if (isinstance(self.norm, colors.BoundaryNorm) or
1245+
self.boundaries is not None):
12411246
y = (self._boundaries - self._boundaries[self._inside][0])
12421247
y = y / (self._boundaries[self._inside][-1] -
12431248
self._boundaries[self._inside][0])

0 commit comments

Comments
 (0)
0