Observação
Clique aqui para baixar o código de exemplo completo
Tutorial do artista #
Usando objetos Artist para renderizar na tela.
Existem três camadas para a API Matplotlib.
a
matplotlib.backend_bases.FigureCanvas
é a área na qual a figura é desenhadao
matplotlib.backend_bases.Renderer
é o objeto que sabe desenhar noFigureCanvas
e o
matplotlib.artist.Artist
é o objeto que sabe como usar um renderizador para pintar na tela.
O FigureCanvas
e
Renderer
lida com todos os detalhes de falar com kits de ferramentas de interface do usuário como wxPython ou linguagens de desenho como PostScript®, e Artist
lida com todas as construções de alto nível, como representar e dispor a figura, o texto e as linhas. O usuário típico gastará 95% do tempo trabalhando com o Artists
.
Existem dois tipos de Artists
: primitivos e contêineres. As primitivas representam os objetos gráficos padrão que queremos pintar em nossa tela:
Line2D
, Rectangle
,
Text
, AxesImage
, etc., e os contêineres são locais para colocá-los ( Axis
,
Axes
e Figure
). O uso padrão é criar uma Figure
instância, usar o Figure
para criar uma ou mais instâncias Axes
ou
Subplot
e usar os Axes
métodos auxiliares de instância para criar as primitivas. No exemplo abaixo, criamos uma
Figure
instância usando matplotlib.pyplot.figure()
, que é um método conveniente para instanciar Figure
instâncias e conectá-las à sua interface de usuário ou kit de ferramentas de desenhoFigureCanvas
. Como discutiremos abaixo, isso não é necessário -- você pode trabalhar diretamente com instâncias PostScript, PDF Gtk+ ou wxPython FigureCanvas
, instanciar suas instâncias Figures
diretamente e conectá-las você mesmo -- mas como estamos focando aqui na
Artist
API, deixaremos pyplot
lidar com algumas desses detalhes para nós:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(2, 1, 1) # two rows, one column, first plot
Esta Axes
é provavelmente a classe mais importante na API do Matplotlib e aquela com a qual você trabalhará na maior parte do tempo. Isso ocorre porque o Axes
é a área de plotagem na qual a maioria dos objetos vai e Axes
tem muitos métodos auxiliares especiais ( plot()
,
text()
,
hist()
,
imshow()
) para criar as primitivas gráficas mais comuns ( Line2D
,
Text
,
Rectangle
,
AxesImage
, respectivamente). Esses métodos auxiliares irão pegar seus dados (por exemplo, numpy
arrays e strings) e criar Artist
instâncias primitivas conforme necessário (por exemplo, Line2D
), adicioná-los aos contêineres relevantes e desenhá-los quando solicitados. A maioria de vocês provavelmente está familiarizada com o Subplot
, que é apenas um caso especial de um Axes
que vive em uma grade regular de linhas por colunas deSubplot
instâncias. Se você deseja criar um Axes
em um local arbitrário, basta usar o
add_axes()
método que recebe uma lista de valores em coordenadas de figura relativa 0-1:[left, bottom, width, height]
fig2 = plt.figure()
ax2 = fig2.add_axes([0.15, 0.1, 0.7, 0.3])
Continuando com nosso exemplo:
Neste exemplo, ax
é a Axes
instância criada pela
fig.add_subplot
chamada acima (lembre -se Subplot
que é apenas uma subclasse de
Axes
) e quando você chama ax.plot
, ele cria uma Line2D
instância e a adiciona ao Axes
.
Na sessão IPython interativa abaixo, você pode ver que a Axes.lines
lista tem comprimento um e contém a mesma linha que foi retornada pela chamada:line, = ax.plot...
In [101]: ax.lines[0]
Out[101]: <matplotlib.lines.Line2D at 0x19a95710>
In [102]: line
Out[102]: <matplotlib.lines.Line2D at 0x19a95710>
Se você fizer chamadas subseqüentes para ax.plot
(e o estado de espera estiver "ligado", que é o padrão), linhas adicionais serão adicionadas à lista. Você pode remover uma linha posteriormente chamando seu remove
método:
The Axes também possui métodos auxiliares para configurar e decorar os marcadores dos eixos x e y, rótulos dos marcadores e rótulos dos eixos:
xtext = ax.set_xlabel('my xdata') # returns a Text instance
ytext = ax.set_ylabel('my ydata')
Quando você chama ax.set_xlabel
, ele passa as informações sobre a Text
instância do XAxis
. Cada Axes
instância contém um XAxis
e uma
YAxis
instância, que lidam com o layout e o desenho dos ticks, rótulos de ticks e rótulos de eixos.
Tente criar a figura abaixo.
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
fig.subplots_adjust(top=0.8)
ax1 = fig.add_subplot(211)
ax1.set_ylabel('volts')
ax1.set_title('a sine wave')
t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2*np.pi*t)
line, = ax1.plot(t, s, color='blue', lw=2)
# Fixing random state for reproducibility
np.random.seed(19680801)
ax2 = fig.add_axes([0.15, 0.1, 0.7, 0.3])
n, bins, patches = ax2.hist(np.random.randn(1000), 50,
facecolor='yellow', edgecolor='yellow')
ax2.set_xlabel('time (s)')
plt.show()
Personalizando seus objetos #
Cada elemento na figura é representado por um Matplotlib
Artist
e cada um possui uma extensa lista de propriedades para configurar sua aparência. A própria figura contém
Rectangle
exatamente o tamanho da figura, que você pode usar para definir a cor de fundo e a transparência das figuras. Da mesma forma, cada Axes
caixa delimitadora (a caixa branca padrão com bordas pretas no gráfico Matplotlib típico tem uma Rectangle
instância que determina a cor, a transparência e outras propriedades dos eixos. Essas instâncias são armazenadas como variáveis de membro Figure.patch
e Axes.patch
("Patch" é um nome herdado do MATLAB e é um "patch" 2D de cor na figura, por exemplo, retângulos, círculos e polígonos). Todo Matplotlib Artist
tem as seguintes propriedades
Propriedade |
Descrição |
---|---|
alfa |
A transparência - um escalar de 0-1 |
animado |
Um booleano que é usado para facilitar o desenho animado |
machados |
Os eixos em que o artista vive, possivelmente nenhum |
clip_box |
A caixa delimitadora que recorta o Artista |
grampear |
Se o recorte está ativado |
clip_path |
O caminho para o qual o artista é recortado |
contém |
Uma função de seleção para testar se o artista contém o ponto de seleção |
figura |
A instância da figura em que o artista vive, possivelmente Nenhuma |
etiqueta |
Um rótulo de texto (por exemplo, para rotulagem automática) |
selecionador |
Um objeto python que controla a seleção de objetos |
transformar |
A transformação |
visível |
Um booleano se o artista deve ser desenhado |
zorder |
Um número que determina a ordem de desenho |
rasterizado |
Boleano; Transforma vetores em gráficos raster (para compressão e transparência EPS) |
Cada uma das propriedades é acessada com um setter ou getter antiquado (sim, sabemos que isso irrita os Pythonistas e planejamos oferecer suporte ao acesso direto por meio de propriedades ou características, mas ainda não foi feito). Por exemplo, para multiplicar o alfa atual pela metade:
a = o.get_alpha()
o.set_alpha(0.5*a)
Se você deseja definir várias propriedades de uma só vez, também pode usar o set
método com argumentos de palavra-chave. Por exemplo:
o.set(alpha=0.5, zorder=2)
Se você estiver trabalhando interativamente no shell python, uma maneira prática de inspecionar as Artist
propriedades é usar a
matplotlib.artist.getp()
função (simplesmente
getp()
em pyplot), que lista as propriedades e seus valores. Isso também funciona para classes derivadas de Artist
, por exemplo, Figure
e Rectangle
. Aqui estão as Figure
propriedades do retângulo mencionadas acima:
In [149]: matplotlib.artist.getp(fig.patch)
agg_filter = None
alpha = None
animated = False
antialiased or aa = False
bbox = Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0)
capstyle = butt
children = []
clip_box = None
clip_on = True
clip_path = None
contains = None
data_transform = BboxTransformTo( TransformedBbox( Bbox...
edgecolor or ec = (1.0, 1.0, 1.0, 1.0)
extents = Bbox(x0=0.0, y0=0.0, x1=640.0, y1=480.0)
facecolor or fc = (1.0, 1.0, 1.0, 1.0)
figure = Figure(640x480)
fill = True
gid = None
hatch = None
height = 1
in_layout = False
joinstyle = miter
label =
linestyle or ls = solid
linewidth or lw = 0.0
patch_transform = CompositeGenericTransform( BboxTransformTo( ...
path = Path(array([[0., 0.], [1., 0.], [1.,...
path_effects = []
picker = None
rasterized = None
sketch_params = None
snap = None
transform = CompositeGenericTransform( CompositeGenericTra...
transformed_clip_path_and_affine = (None, None)
url = None
verts = [[ 0. 0.] [640. 0.] [640. 480.] [ 0. 480....
visible = True
width = 1
window_extent = Bbox(x0=0.0, y0=0.0, x1=640.0, y1=480.0)
x = 0
xy = (0, 0)
y = 0
zorder = 1
As docstrings para todas as classes também contêm as Artist
propriedades, portanto, você pode consultar a "ajuda" interativa ou o
matplotlib.artist para obter uma lista de propriedades para um determinado objeto.
Contêineres de objeto #
Agora que sabemos como inspecionar e definir as propriedades de um determinado objeto que queremos configurar, precisamos saber como chegar a esse objeto. Conforme mencionado na introdução, existem dois tipos de objetos: primitivos e contêineres. Os primitivos são geralmente as coisas que você deseja configurar (a fonte de uma Text
instância, a largura de um Line2D
), embora os contêineres também tenham algumas propriedades - por exemplo, o
é um contêiner que contém muitos dos primitivos em seu gráfico, mas ele também tem propriedades como o para controlar se o xaxis é 'linear' ou 'log'. Nesta seção, revisaremos onde os vários objetos de contêiner armazenam o que você deseja obter.Axes
Artist
xscale
Artists
Figura recipiente #
O contêiner de nível superior Artist
é o
matplotlib.figure.Figure
, e contém tudo na figura. O fundo da figura é um
Rectangle
que está armazenado em
Figure.patch
. Conforme você adiciona subplots ( add_subplot()
) e eixos ( add_axes()
) à figura, eles serão anexados ao arquivo Figure.axes
. Estes também são retornados pelos métodos que os criam:
In [156]: fig = plt.figure()
In [157]: ax1 = fig.add_subplot(211)
In [158]: ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3])
In [159]: ax1
Out[159]: <AxesSubplot:>
In [160]: print(fig.axes)
[<AxesSubplot:>, <matplotlib.axes._axes.Axes object at 0x7f0768702be0>]
Como a figura mantém o conceito dos "Eixos atuais" (consulte
Figure.gca
e
Figure.sca
) para suportar a máquina de estado pylab/pyplot, você não deve inserir ou remover eixos diretamente da lista de eixos, mas usar os
métodos add_subplot()
e
add_axes()
para inserir, e o
Axes.remove
método deletar. Você é livre, no entanto, para iterar na lista de eixos ou indexá-la para obter acesso às Axes
instâncias que deseja personalizar. Aqui está um exemplo que ativa todas as grades de eixos:
for ax in fig.axes:
ax.grid(True)
A figura também tem seus próprios atributos images
, e lines
,
que você pode usar para adicionar primitivas diretamente. Ao fazer isso, o sistema de coordenadas padrão para o será simplesmente em pixels (o que geralmente não é o que você deseja). Se você usar métodos de nível de figura para adicionar artistas (por exemplo, usando para adicionar texto), o sistema de coordenadas padrão será "coordenadas da figura" onde (0, 0) é o canto inferior esquerdo da figura e (1, 1 ) é o canto superior direito da figura.patches
text
Figure
Figure.text
Como acontece com todos os Artist
s, você pode controlar esse sistema de coordenadas definindo a propriedade transform. Você pode usar explicitamente "coordenadas de figura" definindo a Artist
transformação para fig.transFigure
:
import matplotlib.lines as lines
fig = plt.figure()
l1 = lines.Line2D([0, 1], [0, 1], transform=fig.transFigure, figure=fig)
l2 = lines.Line2D([0, 1], [1, 0], transform=fig.transFigure, figure=fig)
fig.lines.extend([l1, l2])
plt.show()
Aqui está um resumo dos Artistas que a Figura contém
Figura atributo |
Descrição |
---|---|
machados |
Uma lista de |
correção |
o |
imagens |
Uma lista de |
legendas |
Uma lista de instâncias de Figure |
linhas |
|
remendos |
Uma lista de Figuras |
Texto:% s |
Uma lista Figura |
Recipiente de eixos #
O matplotlib.axes.Axes
é o centro do universo Matplotlib -- ele contém a grande maioria de todos os Artists
usados em uma figura com muitos métodos auxiliares para criá-los e adicioná-los
Artists
a si mesmo, bem como métodos auxiliares para acessar e personalizar o Artists
que ele contém. Como o
Figure
, contém a
que é a
para coordenadas cartesianas e a
para coordenadas polares; este patch determina a forma, fundo e borda da região de plotagem:Patch
patch
Rectangle
Circle
ax = fig.add_subplot()
rect = ax.patch # a Rectangle instance
rect.set_facecolor('green')
Quando você chama um método de plotagem, por exemplo, o canônico
plot
e passa em arrays ou listas de valores, o método irá criar uma matplotlib.lines.Line2D
instância, atualizar a linha com todas as Line2D
propriedades passadas como argumentos de palavra-chave, adicionar a linha ao Axes
e retornar para você :
In [213]: x, y = np.random.rand(2, 100)
In [214]: line, = ax.plot(x, y, '-', color='blue', linewidth=2)
plot
retorna uma lista de linhas porque você pode passar em vários pares x, y para plotar, e estamos descompactando o primeiro elemento da lista de comprimento um na variável de linha. A linha foi adicionada à
Axes.lines
lista:
In [229]: print(ax.lines)
[<matplotlib.lines.Line2D at 0xd378b0c>]
Da mesma forma, os métodos que criam patches, como
bar()
criar uma lista de retângulos, adicionarão os patches à Axes.patches
lista:
In [233]: n, bins, rectangles = ax.hist(np.random.randn(1000), 50)
In [234]: rectangles
Out[234]: <BarContainer object of 50 artists>
In [235]: print(len(ax.patches))
Out[235]: 50
Você não deve adicionar objetos diretamente às
listas Axes.lines
ou , porque o precisa fazer algumas coisas quando cria e adiciona um objeto:Axes.patches
Axes
Ele define a propriedade
figure
eaxes
doArtist
;Axes
Ele define a transformação padrão (a menos que uma já esteja definida);Ele inspeciona os dados contidos no
Artist
para atualizar as estruturas de dados controlando o dimensionamento automático, para que os limites da visão possam ser ajustados para conter os dados plotados.
Você pode, no entanto, criar objetos e adicioná-los diretamente ao
Axes
usando métodos auxiliares como add_line
e
add_patch
. Aqui está uma sessão interativa anotada ilustrando o que está acontecendo:
In [262]: fig, ax = plt.subplots()
# create a rectangle instance
In [263]: rect = matplotlib.patches.Rectangle((1, 1), width=5, height=12)
# by default the axes instance is None
In [264]: print(rect.axes)
None
# and the transformation instance is set to the "identity transform"
In [265]: print(rect.get_data_transform())
IdentityTransform()
# now we add the Rectangle to the Axes
In [266]: ax.add_patch(rect)
# and notice that the ax.add_patch method has set the axes
# instance
In [267]: print(rect.axes)
Axes(0.125,0.1;0.775x0.8)
# and the transformation has been set too
In [268]: print(rect.get_data_transform())
CompositeGenericTransform(
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())),
CompositeGenericTransform(
BboxTransformFrom(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0),
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())))),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=6.4, y1=4.8),
Affine2D(
[[100. 0. 0.]
[ 0. 100. 0.]
[ 0. 0. 1.]])))))))
# the default axes transformation is ax.transData
In [269]: print(ax.transData)
CompositeGenericTransform(
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())),
CompositeGenericTransform(
BboxTransformFrom(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0),
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())))),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=6.4, y1=4.8),
Affine2D(
[[100. 0. 0.]
[ 0. 100. 0.]
[ 0. 0. 1.]])))))))
# notice that the xlimits of the Axes have not been changed
In [270]: print(ax.get_xlim())
(0.0, 1.0)
# but the data limits have been updated to encompass the rectangle
In [271]: print(ax.dataLim.bounds)
(1.0, 1.0, 5.0, 12.0)
# we can manually invoke the auto-scaling machinery
In [272]: ax.autoscale_view()
# and now the xlim are updated to encompass the rectangle, plus margins
In [273]: print(ax.get_xlim())
(0.75, 6.25)
# we have to manually force a figure draw
In [274]: fig.canvas.draw()
Existem muitos, muitos Axes
métodos auxiliares para criar primitivos
Artists
e adicioná-los aos seus respectivos contêineres. A tabela abaixo resume uma pequena amostra deles, os tipos Artist
que eles criam e onde os armazenam
Método auxiliar de eixos |
Artista |
Recipiente |
---|---|---|
|
ax.textos |
|
|
ax.patches |
|
|
ax.lines e ax.patches |
|
|
ax.patches |
|
|
ax.patches |
|
|
ax.imagens |
|
|
ax.get_legend() |
|
|
ax.lines |
|
|
ax.coleções |
|
|
ax.textos |
Além de todos esses Artists
, o Axes
contém dois Artist
contêineres importantes: o XAxis
e YAxis
, que tratam do desenho dos ticks e rótulos. Estes são armazenados como variáveis de instância
xaxis
e
arquivos yaxis
. Os contêineres XAxis
e YAxis
serão detalhados abaixo, mas observe que Axes
contém muitos métodos auxiliares que encaminham chamadas para as
Axis
instâncias, de modo que você geralmente não precisa trabalhar com eles diretamente, a menos que queira. Por exemplo, você pode definir a cor da fonte dos XAxis
ticklabels usando o Axes
método auxiliar:
ax.tick_params(axis='x', labelcolor='orange')
Abaixo está um resumo dos Artistas que o Axes
contém
Atributo dos eixos |
Descrição |
---|---|
artistas |
uma |
correção |
|
coleções |
uma |
imagens |
um |
linhas |
uma |
remendos |
uma |
Texto:% s |
uma |
eixo x |
Uma |
yaxis |
Uma |
A legenda pode ser acessada por get_legend
,
Contêineres do eixo #
As matplotlib.axis.Axis
instâncias manipulam o desenho das linhas de escala, as linhas de grade, os rótulos de escala e o rótulo de eixo. Você pode configurar as marcações esquerda e direita separadamente para o eixo y e as marcações superior e inferior separadamente para o eixo x. O Axis
também armazena os intervalos de exibição e dados usados no dimensionamento automático, panorâmica e zoom, bem como as instâncias Locator
e
Formatter
que controlam onde os ticks são colocados e como são representados como strings.
Cada Axis
objeto contém um label
atributo (isso é o que pyplot
modifica nas chamadas para xlabel
e
ylabel
) bem como uma lista de ticks principais e secundários. Os ticks são
axis.XTick
e axis.YTick
instâncias, que contêm a linha real e os primitivos de texto que renderizam os ticks e os ticklabels. Como os tiques são criados dinamicamente conforme necessário (por exemplo, ao deslocar e aplicar zoom), você deve acessar as listas de tiques principais e secundários por meio de seus métodos de acesso
axis.Axis.get_major_ticks
e axis.Axis.get_minor_ticks
. Embora os ticks contenham todos os primitivos e serão abordados abaixo, Axis
as instâncias têm métodos de acesso que retornam as linhas de tick, rótulos de tick, locais de tick etc.:
fig, ax = plt.subplots()
axis = ax.xaxis
axis.get_ticklocs()
array([0. , 0.2, 0.4, 0.6, 0.8, 1. ])
[Text(0.0, 0, '0.0'), Text(0.2, 0, '0.2'), Text(0.4, 0, '0.4'), Text(0.6000000000000001, 0, '0.6'), Text(0.8, 0, '0.8'), Text(1.0, 0, '1.0')]
observe que há duas vezes mais linhas de marcação do que rótulos porque, por padrão, existem linhas de marcação na parte superior e inferior, mas apenas etiquetas de marcação abaixo do eixo x; no entanto, isso pode ser personalizado.
<a list of 12 Line2D ticklines objects>
E com os métodos acima, você obtém apenas listas de ticks principais por padrão, mas também pode solicitar os ticks secundários:
axis.get_ticklabels(minor=True)
axis.get_ticklines(minor=True)
<a list of 0 Line2D ticklines objects>
Aqui está um resumo de alguns dos métodos acessadores úteis do Axis
(eles têm setters correspondentes quando úteis, como
set_major_formatter()
.)
Método de acesso do eixo |
Descrição |
---|---|
A escala do Eixo, por exemplo, 'log' ou 'linear' |
|
A instância de intervalo dos limites da visualização Axis |
|
A instância de intervalo dos limites de dados do eixo |
|
Uma lista de linhas de grade para o Eixo |
|
O rótulo Axis - uma |
|
O texto de deslocamento do eixo - uma |
|
Uma lista de |
|
Uma lista de |
|
Uma lista de locais de Tick - palavra-chave minor=True|False |
|
A |
|
A |
|
A |
|
A |
|
Uma lista de |
|
Uma lista de |
|
Ative ou desative a grade para os ticks principais ou secundários |
Aqui está um exemplo, não recomendado por sua beleza, que customiza as propriedades Axes e Tick.
# plt.figure creates a matplotlib.figure.Figure instance
fig = plt.figure()
rect = fig.patch # a rectangle instance
rect.set_facecolor('lightgoldenrodyellow')
ax1 = fig.add_axes([0.1, 0.3, 0.4, 0.4])
rect = ax1.patch
rect.set_facecolor('lightslategray')
for label in ax1.xaxis.get_ticklabels():
# label is a Text instance
label.set_color('red')
label.set_rotation(45)
label.set_fontsize(16)
for line in ax1.yaxis.get_ticklines():
# line is a Line2D instance
line.set_color('green')
line.set_markersize(25)
line.set_markeredgewidth(3)
plt.show()
Tick containers #
O matplotlib.axis.Tick
é o objeto contêiner final em nossa descida do Figure
para o
Axes
para o Axis
para o Tick
. O Tick
contém as instâncias de marca e linha de grade, bem como as instâncias de rótulo para as marcações superiores e inferiores. Cada um deles é acessível diretamente como um atributo do arquivo Tick
.
Atributo de marcação |
Descrição |
---|---|
tick1line |
Uma |
tick2line |
Uma |
linha de grade |
Uma |
label1 |
Uma |
label2 |
Uma |
Aqui está um exemplo que define o formatador para os carrapatos do lado direito com cifrões e os colore de verde no lado direito do yaxis.
import numpy as np
import matplotlib.pyplot as plt
# Fixing random state for reproducibility
np.random.seed(19680801)
fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20))
# Use automatic StrMethodFormatter
ax.yaxis.set_major_formatter('${x:1.2f}')
ax.yaxis.set_tick_params(which='major', labelcolor='green',
labelleft=False, labelright=True)
plt.show()
Tempo total de execução do script: ( 0 minutos 1,067 segundos)