Adding extra contour lines using matplotlib 2D contour plotting - python

I am creating a two-dimensional contour plot with matplotlib. Using the documentation provided http://matplotlib.org/examples/pylab_examples/contour_demo.html, such a contour plot can be created by
import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
plt.figure()
CS = plt.contour(X, Y, Z)
plt.clabel(CS, inline=1, fontsize=10)
plt.title('Simplest default with labels')
which outputs the following plot.
The documentation details how to manually label certain contours (or "lines") on the existing plot. My question is how to create more contour lines than those shown.
For example, the plot shown has two bivariate gaussians. The upper right has three contour lines, at 0.5, 1.0, and 1.5.
How could I add contour lines at say 0.75 and 1.25?
Also, I should be able to zoom in and (in principle) add dozens of dozens of contour lines from (for example) 1.0 and 1.5. How does one do this?

To draw isolines at specified level values, set the levels parameter in .contour:
levels = np.arange(-1.0,1.5,0.25)
CS = plt.contour(X, Y, Z, levels=levels)
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
plt.figure()
levels = np.arange(-1.0,1.5,0.25)
CS = plt.contour(X, Y, Z, levels=levels)
plt.clabel(CS, inline=1, fontsize=10)
plt.title('levels = {}'.format(levels.tolist()))
plt.show()
The sixth figure here uses this method to draw isolines at levels = np.arange(-1.2, 1.6, 0.2).
To zoom in, set the x limits and y limits of the desired region:
plt.xlim(0, 3)
plt.ylim(0, 2)
and to draw, say, 24 automatically-chosen levels, use
CS = plt.contour(X, Y, Z, 24)
For example,
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
plt.figure()
N = 24
CS = plt.contour(X, Y, Z, N)
plt.clabel(CS, inline=1, fontsize=10)
plt.title('{} levels'.format(N))
plt.xlim(0, 3)
plt.ylim(0, 2)
plt.show()
The third figure here uses this method to draw 6 isolines.

Related

fill regions outside contour

Is there any simple way to fill regions outside the contour boundary? Take the following example from matplotlib website:
import numpy as np
import matplotlib.cm as cm
import matplotlib.pyplot as plt
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2
fig, ax = plt.subplots()
CS = ax.contour(X, Y, Z, levels=(0.1, 1.5))
ax.clabel(CS, inline=True, fontsize=10)
This will plot two simple contour of values 0.1 and 1.5.
Now I would like to show regions outside these contours with colors. I tried
ax.contourf(X, Y, Z, levels=(0.1, 1.5))
but this fills regions between 0.1 and 1.5. What can I do to fill outside region but keep inside transparent/white?
(question edited to remove confusing elements from the previous version)

How to color contour labels by a colormap?

I have a contour plot that I color using the Yellow-Green color map named YlGn
The labels at the darker fields do not appear well, as they are black.
Is there a method to color the labels in the inverse of the used colormap? i.e., to color the 0.39 label in white, and the 0.15 label in dark green, and the labels in-between accordingly.
I used CS3 = plt.contourf(X, Z, M, levels, cmap=plt.cm.YlGn, extend='both') for the filled contour and CS4 = plt.contour(CS3, colors=('k',), linewidths=(1,)) for the line contour, and finally plt.clabel(CS4, linewidths=2, fmt='%2.2f', colors='k', fontsize=14) for the labels.
However when I tried to add cmap=plt.cm.YlGn_r and removed the colors='k' to the labels (to reverse the colors) it did nothing.
Note: The codes used here are partially taken from this documentation page, but with some modifications to fit my data.
Here are some data to try at a Jupyter notebook:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'
delta = 0.025
x = np.arange(1.0, 3.0, delta)
y = np.arange(1.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
plt.figure()
CS = plt.contour(X, Y, Z, cmap=plt.cm.YlGn_r)
CS2 = plt.contourf(X, Y, Z, color='k')
plt.clabel(CS, fontsize=10,color='k')
plt.title('Simplest default with labels')
I guess you mixed up the arguments to contour and contourf. Applying the reverse colormap to contour works fine.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import mlab
delta = 0.025
x = np.arange(1.0, 3.0, delta)
y = np.arange(1.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
plt.figure()
CS2 = plt.contourf(X, Y, Z, cmap=plt.cm.YlGn_r)
CS = plt.contour(X, Y, Z, cmap=plt.cm.YlGn)
plt.clabel(CS, fontsize=10)
plt.title('Simplest default with labels')
plt.show()
To use the same colormap for the lines as for the fills, but then use a different colormap for the labels, you need to define the colors manually. But the use of the existing levels helps you do that quite efficiently.
CS2 = plt.contourf(X, Y, Z, cmap=plt.cm.YlGn_r)
CS = plt.contour(CS2, cmap=plt.cm.YlGn_r)
plt.clabel(CS, fontsize=10, colors=plt.cm.Reds(CS.norm(CS.levels)))

change dash style of negative values in a default contour - matplotlib

I am trying to plot contours with matplotlib and I have negative values in the data and I want them to be dashed(which matplotlib does by default) however, I want to (1) control the dash style (on,off) and (2) change the color for the negative contours alone. I tried the answer in link: How can I set the dash length in a matplotlib contour plot
But this sets all the lines in the contour to dashes which I do not want. I need to hack the negative contour line styles alone!
A part of my code:
from pylab import *
import matplotlib
import numpy as np
matplotlib.rcParams['contour.negative_linestyle']= 'dashed'
CS = ax1.contour(xi, yi, W_t, levels=levels, colors='k', linewidths=0.05)
for c in CS.collections:
c.set_dashes([(0, (2.0, 2.0))])
You can loop though the line collections created by the CS object and for any non solid lines (from get_linetype with value [(None, None)]) set them however you want. As a minimal example,
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
#Dummy data
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
Z = 10.0 * (Z2 - Z1)
CS = plt.contour(X, Y, Z, 20, colors='k')
for line in CS.collections:
if line.get_linestyle() == [(None, None)]:
print("Solid Line")
else:
line.set_linestyle([(0, (12.0, 3.0))])
line.set_color('red')
plt.show()

Contour plot python, how to change labels

I would like to change what I am labeling. I mean, instead of the values of the levels I would like to write something different. For instance in a plot like the first one in http://matplotlib.org/examples/pylab_examples/contour_demo.html I would like to change 1.500, 1.000, 0.5 for 56%, 34%,23%. Is it possible?
You can do something similar on these terms:
import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.ticker as ticker
import matplotlib.pyplot as plt
matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'
##################################################
# Define our surface
##################################################
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
CS = plt.contour(X, Y, Z)
fmt = {}
strs = [ '54%', '10%', '3%', '47%', '51%', '66%', '7%' ]
for l,s in zip( CS.levels, strs ):
fmt[l] = s
# Label every other level using strings
plt.clabel(CS,CS.levels[::2],inline=True,fmt=fmt,fontsize=10)
plt.show()

Matplotlib: same height for colorbar as for plot [duplicate]

This question already has answers here:
Set Matplotlib colorbar size to match graph
(9 answers)
Closed 8 years ago.
I'm plotting some 2D data as shown. The axes aspect should be equal and the axes range should differ.
import numpy
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
#Generate data
delta = 0.025
x = numpy.arange(-5.0, 5.0, delta)
y = numpy.arange(-5.0, 5.0, delta)
X, Y = numpy.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
#Plot
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1, aspect='equal')
PC = ax1.pcolor(X, Y, Z)
CF = ax1.contour(X, Y, Z, 50, colors = "black")
plt.xlim(-4.0, 4.0)
plt.ylim(-2.0, 2.0)
cbar = plt.colorbar(PC)
cbar.add_lines(CF)
plt.show()
How can I make the colobar has the same height as the plotted data?
You can do this using make_axes_locatable:
import numpy
import matplotlib.pyplot as plt
import matplotlib.mlab as mlab
from mpl_toolkits.axes_grid1 import make_axes_locatable
#Generate data
delta = 0.025
x = numpy.arange(-5.0, 5.0, delta)
y = numpy.arange(-5.0, 5.0, delta)
X, Y = numpy.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
#Plot
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1, aspect='equal')
PC = ax1.pcolor(X, Y, Z)
CF = ax1.contour(X, Y, Z, 50, colors = "black")
plt.xlim(-4.0, 4.0)
plt.ylim(-2.0, 2.0)
divider = make_axes_locatable(ax1)
cax1 = divider.append_axes("right", size="5%", pad=0.05)
cbar = plt.colorbar(PC, cax = cax1)
cbar.add_lines(CF)
plt.show()

Categories

Resources