Skip to content

Navigation Menu

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

Appearance settings

[Bug]: slow rendering of multiple axes (time scales as 2nd power of label count) #21895

Copy link
Copy link
Closed
@FilipDominec

Description

@FilipDominec
Issue body actions

Bug summary

I need to label a lot of elemental emission peaks on X-ray spectra. There are three series of peaks denoted K, L and M, so I put three axes above the plot. (This is the best approach I could find online, it does not seem that multiple text labels would be covered in the docs. I will be thankful for any tip.)

Anyway, the plotting then goes very very slow: roughly 4× slower when the number of labels doubles.

Code for reproduction

#!/usr/bin/python3  
#-*- coding: utf-8 -*-

## Import common moduli
import matplotlib, sys
matplotlib.use("cairo") # helps a bit
#matplotlib.rc('text', usetex=False)
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(16, 10))
x,y = [1,2,3], [5,6,4] ## dummy data
#x,y = np.
ax.plot(x,y, marker='o')

elem = ["H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne",  "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es"][:int(sys.argv[1]) if len(sys.argv)>1 else 1000]


max_x = 14
use_math = False

if max_x: ax.set_xlim(xmin=0, xmax=max_x)

posK = np.arange(len(elem))**2 *3/4*0.0136 # a bit inaccurate Moseley law for K-series
ax2 = ax.twiny()
ax2.plot(x,y, color="None")
ax2.set_xticks(posK)  # (must precede set_xlim)
if use_math:
    ax2.set_xticklabels((s+"$_K$" for s in elem), fontsize=8) 
else:
    ax2.set_xticklabels((s+"K" for s in elem), fontsize=8)  # helps a bit
if max_x: ax2.set_xlim(xmin=0, xmax=max_x)

posL = np.arange(len(elem))**2 *3/4*0.0136 / 3.9 # very inaccurate Moseley law for L-series
ax3 = ax.twiny()
ax3.plot(x,y, color="None")
ax3.set_xticks(posL) 
if use_math:
    ax3.set_xticklabels((s+"$_L$" for s in elem), fontsize=8) 
else:
    ax3.set_xticklabels((s+"_L" for s in elem), fontsize=8) 
if max_x: ax3.set_xlim(xmin=0, xmax=max_x)
ax3.spines["top"].set_position(("axes", 1.05))

posM = np.arange(len(elem))**2 *3/4*0.0136 / 9.9 # very inaccurate Moseley law for M-series
ax4 = ax.twiny()
ax4.plot(x,y, color="None")
ax4.set_xticks(posM) 
if use_math:
    ax4.set_xticklabels((s+"$_M$" for s in elem), fontsize=8) 
else:
    ax4.set_xticklabels((s+"_M" for s in elem), fontsize=8) 
if max_x: ax4.set_xlim(xmin=0, xmax=max_x)
ax4.spines["top"].set_position(("axes", 1.10))

print('ready to output', flush=True)
fig.savefig("output.png", bbox_inches='tight')

Actual outcome

By default QtAgg is used. With use_math=True it takes 1m59,698s, without it only 0m18,759s.

When I switch backend to cairo: With use_math=True it takes 1m30,385s, without it only 0m11,522s. Still a lot.

output

Expected outcome

Such a simple plot could render within few seconds, even if lower indices are used rendered using the $ ... $ notation.

Also, as a separate minor bug, I can see fontsize=8 has applied on the first extra axis only. The other two would not change their font size even when explicitly asked for.

Additional information

This bug was observed also in Matplotlib 3.1.x taken from the Ubuntu repository. Today I checked out the devel version and it is basically the same.

Almost all the code runs within a second. The slow command is the savefig.

I don't know why this happens, it looks like if every next label somehow needed to "update" all existing ones; this would explain the quadratic dependence of time.

I don't know any fix.

Operating system

Ubuntu

Matplotlib Version

3.6.0.dev995+g21b76ae7f7

Matplotlib Backend

QtAgg by default,

Python version

Python 3.8.10 (default, Sep 28 2021, 16:10:42)

Jupyter version

N/A

Installation

git checkout

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.