# Python/Matplotlib - Is there a way to make a discontinuous axis?

I'm trying to create a plot using pyplot that has a discontinuous x-axis. The usual way this is drawn is that the axis will have something like this:

(values)----//----(later values)

where the // indicates that you're skipping everything between (values) and (later values).

I haven't been able to find any examples of this, so I'm wondering if it's even possible. I know you can join data over a discontinuity for, eg, financial data, but I'd like to make the jump in the axis more explicit. At the moment I'm just using subplots but I'd really like to have everything end up on the same graph in the end.

35

Paul's answer is a perfectly fine method of doing this.

However, if you don't want to make a custom transform, you can just use two subplots to create the same effect.

Rather than put together an example from scratch, there's an excellent example of this written by Paul Ivanov in the matplotlib examples (It's only in the current git tip, as it was only committed a few months ago. It's not on the webpage yet.).

This is just a simple modification of this example to have a discontinuous x-axis instead of the y-axis. (Which is why I'm making this post a CW)

Basically, you just do something like this:

``````import matplotlib.pylab as plt
import numpy as np

# a series with points from 0 to 1 spaced at 0.1, and 9 to 10 with the same spacing.
x = np.r_[0:1:0.1, 9:10:0.1]
y = np.sin(x)

fig,(ax,ax2) = plt.subplots(1, 2, sharey=True)

# plot the same data on both axes
ax.plot(x, y, 'bo')
ax2.plot(x, y, 'bo')

# zoom-in / limit the view to different portions of the data
ax.set_xlim(0,1) # most of the data
ax2.set_xlim(9,10) # outliers only

# hide the spines between ax and ax2
ax.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax.yaxis.tick_left()
ax.tick_params(labeltop='off') # don't put tick labels at the top
ax2.yaxis.tick_right()

# Make the spacing between the two axes a bit smaller

plt.show()
`````` To add the broken axis lines `//` effect, we can do this (again, modified from Paul Ivanov's example):

``````import matplotlib.pylab as plt
import numpy as np

# a series with points from 0 to 1 spaced at 0.1, and 9 to 10 with the same spacing.
x = np.r_[0:1:0.1, 9:10:0.1]
y = np.sin(x)

fig,(ax,ax2) = plt.subplots(1, 2, sharey=True)

# plot the same data on both axes
ax.plot(x, y, 'bo')
ax2.plot(x, y, 'bo')

# zoom-in / limit the view to different portions of the data
ax.set_xlim(0,1) # most of the data
ax2.set_xlim(9,10) # outliers only

# hide the spines between ax and ax2
ax.spines['right'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax.yaxis.tick_left()
ax.tick_params(labeltop='off') # don't put tick labels at the top
ax2.yaxis.tick_right()

# Make the spacing between the two axes a bit smaller

# This looks pretty good, and was fairly painless, but you can get that
# cut-out diagonal lines look with just a bit more work. The important
# thing to know here is that in axes coordinates, which are always
# between 0-1, spine endpoints are at these locations (0,0), (0,1),
# (1,0), and (1,1). Thus, we just need to put the diagonals in the
# appropriate corners of each of our axes, and so long as we use the
# right transform and disable clipping.

d = .015 # how big to make the diagonal lines in axes coordinates
# arguments to pass plot, just so we don't keep repeating them
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((1-d,1+d),(-d,+d), **kwargs) # top-left diagonal
ax.plot((1-d,1+d),(1-d,1+d), **kwargs) # bottom-left diagonal

kwargs.update(transform=ax2.transAxes) # switch to the bottom axes
ax2.plot((-d,d),(-d,+d), **kwargs) # top-right diagonal
ax2.plot((-d,d),(1-d,1+d), **kwargs) # bottom-right diagonal

# ax and ax2 via f.subplots_adjust(hspace=...) or plt.subplot_tool(),
# the diagonal lines will move accordingly, and stay right at the tips
# of the spines they are 'breaking'

plt.show()
`````` Tuesday, June 1, 2021

86

Yes. You need to read about media queries. They allow your page to adapt to screen sized allowing your content to be enhanced for mobile and desktop browsing. take a look here:

http://css-tricks.com/css-media-queries/

Wednesday, March 31, 2021

71

You could do this (just an outlined idea, no code):

Devise a regex that matches your entire text. Use fixed strings for the unmodifiable parts, and use `[sS]*?` for the modifiable parts. Use `^` and `\$` to anchor your regex.

``````/^This is fixed text. Now something editable:[sS]*?Now fixed again.\$/
``````

Now react to the `keyup` event, and probably other events as well (like `paste`).

With every relevant event, make a check if the regex still matches.

If it doesn't, cancel the event.

Effectively, this should stop modifications to parts that are literal in the regex and thus make certain parts of your text read-only.

Don't forget to test the string on the server side as well after the form post - never trust that the client cannot send invalid values.

EDIT

You can use a regex quote function to dynamically build that regex from strings, this should save you a lot of the hassle.

``````function regexQuote(s) { return s.replace(/[[]^\$*+?{}.|\]/g, "\\$&") }
``````

usage

``````var re = new Regex(
"^" +
[regexQuote(fixedPart1), regexQuote(fixedPart2)].join("[\s\S].*?")
+ "\$"
);
``````
Monday, June 14, 2021

59

To summarize: matplotlib requires a config file names matplotlibrc to be found in one of 4 specific locations, the first one being the courant directory (see https://matplotlib.org/tutorials/introductory/customizing.html#the-matplotlibrc-file) One this file prepared as per need it can be embeeded in the exe by adding --add-data=matplotlibrc;. to the build command (replace ; with : for non-Windows systems)

Thursday, November 18, 2021

72

If you are having trouble with a matplotlib backend try selecting a different one.
Matplotlib caters for many different scenarios and uses.
On Linux, I use the following code to select whichever backend is available and works first.

``````import matplotlib
gui_env = ['TKAgg','GTKAgg','Qt4Agg','WXAgg']
for gui in gui_env:
try:
matplotlib.use(gui,warn=False, force=True)
from matplotlib import pyplot as plt
break
except:
continue
``````

or if you are going to be creating an image file rather than displaying it

Use:

``````matplotlib.use('agg')
from matplotlib import pyplot as plt
``````

Edit:
Based on your comments try this and see if you get a result that works.

``````import matplotlib
gui_env = [i for i in matplotlib.rcsetup.interactive_bk]
print ("I will test for", gui_env)
for gui in gui_env:
print ("testing", gui)
try:
matplotlib.use(gui,warn=False, force=True)
from matplotlib import pyplot as plt
print ("    ",gui, "Is Available")
plt.plot([1.5,2.0,2.5])
fig = plt.gcf()
fig.suptitle(gui)
plt.show()
print ("Using ..... ",matplotlib.get_backend())
except: