module faq.faq_matplotlib#

Short summary#

module ensae_teaching_cs.faq.faq_matplotlib

Quelques problèmes récurrents avec matplotlib.

source on GitHub

Functions#

function

truncated documentation

avoid_overlapping_dates

Avoids overlapping dates by calling method autofmt_xdate.

change_legend_location

Changes the location of the legend.

close_all

Closes every graph with matplotlib.

graph_cities

Plots the cities on a map with cartopy. Only not empty names are displayed on the graph.

graph_cities_default_lands

Returns the default list of elements which can be added to a map. See Features. …

graph_style

Changes matplotlib style.

graph_with_label

Creates a graph with matplotlib.

Documentation#

Quelques problèmes récurrents avec matplotlib.

source on GitHub

ensae_teaching_cs.faq.faq_matplotlib.avoid_overlapping_dates(fig, **options)#

Avoids overlapping dates by calling method autofmt_xdate.

Comment éviter les dates qui se superposent ?

La méthode autofmt_xdate permet d’éviter les problèmes de dates qui se superposent.

fig, ax = plt.subplots(...)
# ...
fig.autofmt_xdate()

source on GitHub

ensae_teaching_cs.faq.faq_matplotlib.change_legend_location(ax, new_location='lower center')#

Changes the location of the legend.

Paramètres:
  • axAxes

  • new_location – new_location, see method legend

Renvoie:

ax

Comment changer l’emplacement de la légende ?

On cherche ici à changer l’emplacement de la légende alors que celle-ci a déjà été définie par ailleurs. C’est pratique lorsque celle-ci cache une partie du graphe qu’on veut absolument montrer. On ne dispose que de l’objet ax de type Axes. On utilise pour cela la méthode legend et le code suivant :

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels, loc="lower center")

Les différentes options pour le nouvel emplacement sont énoncées dans l’aide associée à la méthode legend.

source on GitHub

ensae_teaching_cs.faq.faq_matplotlib.close_all()#

Closes every graph with matplotlib.

Plante après plusieurs graphes

Il peut arriver que matplotlib fasse planter python sans qu’aucune exception ne soit générée. L’article matplotlib crashing Python suggère la solution suivante

import matplotlib.pyplot as plt
plt.close('all')

Voir close.

source on GitHub

ensae_teaching_cs.faq.faq_matplotlib.graph_cities(df, names=('Longitude', 'Latitude', 'City'), ax=None, linked=False, fLOG=None, loop=False, many=False, draw_coastlines=True, draw_countries=True, fill_continents=True, draw_parallels=True, draw_meridians=True, draw_map_boundary=True, **params)#

Plots the cities on a map with cartopy. Only not empty names are displayed on the graph.

Paramètres:
  • df – dataframe

  • names – names of the column Latitude, Longitude, City

  • ax – existing ax

  • linked – draw lines between points

  • loop – add a final line to link the first point to the final one

  • fLOG – logging function

  • params – see below

  • many – change the return

  • draw_coastlines – draw coast lines

  • draw_countries – draw borders

  • draw_map_boundary – draw boundaries

  • draw_meridians – draw meridians

  • draw_parallels – draw parallels

  • fill_continents – fill continents

Renvoie:

ax or fig, ax, m if many is True

Additional parameters:

  • projection: see projections, only used is ax is None

  • bounds: something like [lon1, lon2, lat1, lat2]

  • landscape: a list of strings about what needs to be on the map, see graph_cities_default_lands.

  • style, markersize, fontname, fontcolor, fontsize, fontweight, fontvalign

If the function returns the following error 'AxesSubplot' object has no attribute 'add_feature', it means no projection was added to the axis. The function currently creates the following way:

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
projection = params.pop('projection', ccrs.PlateCarree())
fig = plt.figure(**params)
ax = fig.add_subplot(1, 1, 1, projection)

source on GitHub

ensae_teaching_cs.faq.faq_matplotlib.graph_cities_default_lands()#

Returns the default list of elements which can be added to a map. See Features.

<<<

from ensae_teaching_cs.faq.faq_matplotlib import graph_cities_default_lands
print(graph_cities_default_lands())

>>>

    ['BORDERS', 'COASTLINE', 'LAKES', 'LAND', 'OCEAN', 'RIVERS']

source on GitHub

ensae_teaching_cs.faq.faq_matplotlib.graph_style(style='ggplot')#

Changes matplotlib style.

Paramètres:

style – style

Changer le style de graphique pour ggplot

Voir Customizing plots with style sheets

import matplotlib.pyplot as plt
plt.style.use('ggplot')

source on GitHub

ensae_teaching_cs.faq.faq_matplotlib.graph_with_label(x, y, labels, barplot=True, title=None, figsize=(6, 4), style=None, ax=None, **kwargs)#

Creates a graph with matplotlib.

Paramètres:
  • x – x

  • y – y

  • labels – x labels

  • barplot – boolean, True, uses bar, plot otherwise

  • title – if not None, sets the title

  • figsize – only if ax is not None

  • style – style

  • ax – existing Axes or None if it must be created

  • kwargs – others parameters

Renvoie:

Axes

Comment ajuster les labels non numériques d’un graphe ?

Lorsqu’on trace un graphique et qu’on veut ajouter des labels non numériques sur l’axe des abscisses (en particulier des dates), matplotlib ne fait pas apparaître tous les labels. Ainsi, si on a 50 points, 50 abscisses et 50 labels, seuls les premiers labels apparaîtront comme ceci :

import matplotlib.pyplot as plt
x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
     28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43]
y = [1, 3, 10, 6, 3, 5, 3, 6, 4, 2, 3, 2, 11, 10, 4, 5, 2, 5, 4, 1, 1, 1, 3, 15, 5, 2, 1, 5, 3, 1, 3,
     2, 4, 5, 2, 12, 12, 5, 11, 2, 19, 21, 5, 2]
xl = ['2014-w04', '2014-w05', '2014-w06', '2014-w07', '2014-w08', '2014-w09',
      '2014-w10', '2014-w11',
      '2014-w12', '2014-w13', '2014-w14', '2014-w15', '2014-w16',
      '2014-w17', '2014-w18', '2014-w19', '2014-w20', '2014-w21', '2014-w22', '2014-w23',
      '2014-w24', '2014-w25', '2014-w27',
      '2014-w29', '2014-w30', '2014-w31', '2014-w32', '2014-w34', '2014-w35', '2014-w36',
      '2014-w38', '2014-w39', '2014-w41',
      '2014-w42', '2014-w43', '2014-w44', '2014-w45', '2014-w46', '2014-w47', '2014-w48',
      '2014-w49', '2014-w50', '2014-w51', '2014-w52']
plt.close('all')
fig,ax = plt.subplots(nrows=1,ncols=1,figsize=(10,4))
ax.bar( x,y )
ax.set_xticklabels( xl )
ax.grid(True)
ax.set_title("commits")
plt.show()

(png, hires.png, pdf)

../../_images/faq_matplotlib-1.png

Or c’est cela qu’on veut :

import matplotlib.pyplot as plt
x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
     32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43]
y = [1, 3, 10, 6, 3, 5, 3, 6, 4, 2, 3, 2, 11, 10, 4, 5, 2, 5, 4, 1, 1, 1, 3, 15, 5, 2, 1, 5,
     3, 1, 3, 2, 4, 5, 2, 12, 12, 5, 11, 2, 19, 21, 5, 2]
xl = ['2014-w04', '2014-w05', '2014-w06', '2014-w07', '2014-w08', '2014-w09',
      '2014-w10', '2014-w11', '2014-w12', '2014-w13', '2014-w14',
      '2014-w15', '2014-w16', '2014-w17', '2014-w18', '2014-w19',
      '2014-w20', '2014-w21', '2014-w22', '2014-w23', '2014-w24', '2014-w25',
      '2014-w27', '2014-w29', '2014-w30', '2014-w31', '2014-w32', '2014-w34',
      '2014-w35', '2014-w36', '2014-w38', '2014-w39', '2014-w41',
      '2014-w42', '2014-w43', '2014-w44', '2014-w45', '2014-w46', '2014-w47',
      '2014-w48', '2014-w49', '2014-w50', '2014-w51', '2014-w52']
plt.close('all')
fig,ax = plt.subplots(nrows=1,ncols=1,figsize=(10,4))
ax.bar( x,y )
tig = ax.get_xticks()
labs = [ ]
for t in tig:
    if t in x: labs.append(xl[x.index(t)])
    else: labs.append("")
ax.set_xticklabels( labs )
ax.grid(True)
ax.set_title("commits")
plt.show()

(png, hires.png, pdf)

../../_images/faq_matplotlib-2.png

Pour cela il faut d’abord utiliser la méthode get_xticks pour récupérer d’abord les graduations et n’afficher les labels que pour celles-ci (voir aussi Custom ticks autoscaled when using imshow?). Voici un exemple de code

import matplotlib.pyplot as plt
x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
     30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43]
y = [1, 3, 10, 6, 3, 5, 3, 6, 4, 2, 3, 2, 11, 10, 4, 5, 2, 5, 4, 1, 1, 1, 3, 15, 5, 2, 1, 5, 3, 1, 3, 2,
     4, 5, 2, 12, 12, 5, 11, 2, 19, 21, 5, 2]
xl = ['2014-w04', '2014-w05', '2014-w06', '2014-w07', '2014-w08', '2014-w09', '2014-w10', '2014-w11', '2014-w12', '2014-w13',
      '2014-w14', '2014-w15', '2014-w16', '2014-w17', '2014-w18', '2014-w19', '2014-w20', '2014-w21',
      '2014-w22', '2014-w23', '2014-w24', '2014-w25',
      '2014-w27', '2014-w29', '2014-w30', '2014-w31', '2014-w32', '2014-w34', '2014-w35', '2014-w36',
      '2014-w38', '2014-w39', '2014-w41', '2014-w42',
      '2014-w43', '2014-w44', '2014-w45', '2014-w46', '2014-w47', '2014-w48', '2014-w49',
      '2014-w50', '2014-w51', '2014-w52']
plt.close('all')
fig,ax = plt.subplots(nrows=1,ncols=1,figsize=(10,4))
ax.bar( x,y )
tig = ax.get_xticks()
labs = [ ]
for t in tig:
    if t in x:
        labs.append(xl[x.index(t)])
    else:
        # une graduation peut être en dehors des labels proposés
        labs.append("")
ax.set_xticklabels( labs )
ax.grid(True)
ax.set_title("commits")
plt.show()

source on GitHub