Contourf not showing full range of values - python

I have two datasets that when compared result in a basically random distribution of values between -1 and 1. When I plot this using contourf, however, the figure shows almost all values > 0.5. When I plot every 10th point (thin the data), I get a graph that is more reasonable. But it is not clear why the contourf function is doing this.
I replicated this using a random number list of the same size as my data. The result is the same.
import numpy as np
import matplotlib.pyplot as plt
from netCDF4 import Dataset
from matplotlib.cm import get_cmap
import numpy as np
random = np.random.random((360,1600))*2.-1.
f, ax = plt.subplots(1,2,figsize=(15,5))
#heights = ax.contour(to_np(hgt),3,colors='k')
#ax.clabel(heights, fmt='%2.0f', colors='k', fontsize=8)
#cbar = f.colorbar(heights)
#heights.levels=[0,100,3000]
#plt.clabel(heights, heights.levels)
clevs = [-0.5,-0.1,0.1,0.5]
diffplot = ax[0].contourf(random[::10,::10],clevs,extend='both')
cbar = f.colorbar(diffplot,ax=ax[0])
clevs = [-0.5,-0.1,0.1,0.5]
diffplot2 = ax[1].contourf(random[:,:],clevs,extend='both')
cbar = f.colorbar(diffplot2,ax=ax[1])
Result of code

The full range is shown, but the issue is in the large number of points vs. resolution.
That means points drawn 'later' (aka the ones at the end of the color levels range = higher values) have a certain minimum size (you still need to see them) that then overlaps previous (aka smaller values) points, resulting in the image colors looking skewed.
Solution is to increase the dpi of the figure (matplotlib default is 100dpi):
Note how the reduced points from your example plotted on the left hand side looks the same but the right hand side only looks similar >=300 dpi.
Code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.cm import get_cmap
import numpy as np
random = np.random.random((360,1600))*2.-1.
clevs = [-0.5,-0.1,0.1,0.5]
f1, ax = plt.subplots(1,2,figsize=(15,5)) # ,dpi=100
diffplot = ax[0].contourf(random[::10,::10],clevs,extend='both')
cbar = f1.colorbar(diffplot,ax=ax[0])
diffplot2 = ax[1].contourf(random[:,:],clevs,extend='both')
cbar = f1.colorbar(diffplot2,ax=ax[1])
f1.set_dpi(100)
f1.suptitle('dpi = 100', fontweight = 'bold', fontsize = 20)
f2, ax = plt.subplots(1,2,figsize=(15,5)) # ,dpi=150
diffplot = ax[0].contourf(random[::10,::10],clevs,extend='both')
cbar = f2.colorbar(diffplot,ax=ax[0])
diffplot2 = ax[1].contourf(random[:,:],clevs,extend='both')
cbar = f2.colorbar(diffplot2,ax=ax[1])
f2.set_dpi(150)
f2.suptitle('dpi = 150', fontweight = 'bold', fontsize = 20)
f3, ax = plt.subplots(1,2,figsize=(15,5)) # ,dpi=300
diffplot = ax[0].contourf(random[::10,::10],clevs,extend='both')
cbar = f3.colorbar(diffplot,ax=ax[0])
diffplot2 = ax[1].contourf(random[:,:],clevs,extend='both')
cbar = f3.colorbar(diffplot2,ax=ax[1])
f3.set_dpi(300)
f3.suptitle('dpi = 300', fontweight = 'bold', fontsize = 20)
f4, ax = plt.subplots(1,2,figsize=(15,5)) # ,dpi=600
diffplot = ax[0].contourf(random[::10,::10],clevs,extend='both')
cbar = f4.colorbar(diffplot,ax=ax[0])
diffplot2 = ax[1].contourf(random[:,:],clevs,extend='both')
cbar = f4.colorbar(diffplot2,ax=ax[1])
f4.set_dpi(600)
f4.suptitle('dpi = 600', fontweight = 'bold', fontsize = 20)
f5, ax = plt.subplots(1,2,figsize=(15,5)) # ,dpi=900
diffplot = ax[0].contourf(random[::10,::10],clevs,extend='both')
cbar = f5.colorbar(diffplot,ax=ax[0])
diffplot2 = ax[1].contourf(random[:,:],clevs,extend='both')
cbar = f5.colorbar(diffplot2,ax=ax[1])
f5.set_dpi(900)
f5.suptitle('dpi = 900', fontweight = 'bold', fontsize = 20)
plt.show()
Note the two options for setting the dpi:
fig, ax = plt.subplots(1,2,figsize=(15,5), dpi=600)
# or
fig.set_dpi(600)
An explanation from another angle - bare with me for some plots:
Note: The following plots are arranged with gridspec to be shown in a single figure.
That way the 'resolution' is depicted in a comparable way.
1) The effect you recognized depends on the plot size
See the code below, all 3 plots contain the same data ..., the only difference is their size.
Notice how with the increased size the colors distribution looks more and more as expected.
from matplotlib import gridspec
import numpy as np
import matplotlib.pyplot as plt
random = np.random.random((360,1600))*2.-1.
#random = np.random.random((100,100))*2.-1.
clevs = [-0.5,-0.1,0.1,0.5]
fig = plt.figure(figsize=(18,20), facecolor=(1, 1, 1))
gs = gridspec.GridSpec(3, 4, height_ratios=[1,1,4])
cmap='viridis' # Note: 'viridis' is the default cmap
ax1 = fig.add_subplot(gs[0,:1])
ax1.set_title('ax1')
diffplot1 = ax1.contourf(random[:,:],clevs,extend='both', cmap=cmap)
fig.colorbar(diffplot1, ax=ax1)
ax2 = fig.add_subplot(gs[0:2,2:])
ax2.set_title('ax2')
diffplot2 = ax2.contourf(random[:,:],clevs,extend='both', cmap=cmap)
fig.colorbar(diffplot2, ax=ax2)
ax3 = fig.add_subplot(gs[2,:])
ax3.set_title('ax3')
diffplot3 = ax3.contourf(random[:,:],clevs,extend='both', cmap=cmap)
fig.colorbar(diffplot3, ax=ax3)
fig.tight_layout()
# plt.savefig("Contourf_Colorbar.png")
plt.show()
2) The effect you recognized depends on number of points 'cramped' into a plot
Basically the same that you've already noticed in your question with plotting only every 10th value.
Notice how the colors distribution looks as expected kinda the same for the 3 plot sizes.
Activate random = np.random.random((100,100))*2.-1. in the code block above to get this plot.
3) Reversed color cmap as another way of showing the effect
Notice how this is like the plot from 1) but just with reversed colors.
from matplotlib import gridspec
import numpy as np
import matplotlib.pyplot as plt
random = np.random.random((360,1600))*2.-1.
clevs = [-0.5,-0.1,0.1,0.5]
fig = plt.figure(figsize=(18,20), facecolor=(1, 1, 1))
gs = gridspec.GridSpec(3, 4, height_ratios=[1,1,4])
# reverse cmap
cmap='viridis' # Note: 'viridis' is the default cmap
cmap=plt.cm.get_cmap(cmap)
cmap = cmap.reversed()
ax1 = fig.add_subplot(gs[0,:1])
ax1.set_title('ax1')
diffplot1 = ax1.contourf(random[:,:],clevs,extend='both', cmap=cmap)
fig.colorbar(diffplot1, ax=ax1)
ax2 = fig.add_subplot(gs[0:2,2:])
ax2.set_title('ax2')
diffplot2 = ax2.contourf(random[:,:],clevs,extend='both', cmap=cmap)
fig.colorbar(diffplot2, ax=ax2)
ax3 = fig.add_subplot(gs[2,:])
ax3.set_title('ax3')
diffplot3 = ax3.contourf(random[:,:],clevs,extend='both', cmap=cmap)
fig.colorbar(diffplot3, ax=ax3)
fig.tight_layout()
# plt.savefig("Contourf_Colorbar_reverse.png")
plt.show()
Finally for reference from matplotlib contourf docu:
algorithm{'mpl2005', 'mpl2014', 'serial', 'threaded'}, optional
Which contouring algorithm to use to calculate the contour lines and polygons. The algorithms are implemented in ContourPy, consult the
ContourPy documentation for further information.
The default is taken from rcParams["contour.algorithm"] (default: 'mpl2014').
I've tried some options (wasn't able to get algorithm going, but checked antialiased ... actually more in a try&error method) without an improvement.
But you could look into the referenced ContourPy to maybe find a way to reduce the 'size of the dots' that are drawn, but that's out of my league.

Related

UnivariateSpline equivalent for exponential functions?

I currently have a set of data that I wish to make a function out of that is defined for all values of possible values of temp_vp (my x data in this case)
temp_vp = [280.0,290.0,300.0,310.0,320.0,330.0,340.0,350.0,360.0,370.0,380.0,390.0,400.0,410.0,420.0,430.0,440.0,450.0,460.0,470.0,480.0,490.0,500.0]
vp_in = [3.88e-52,5.16e-50,4.95e-48,3.53e-46,1.93e-44,8.26e-43,2.83e-41,7.93e-40,1.85e-38,3.62e-37,6.07e-36,8.79e-35,1.11e-33,1.25e-32,1.24e-31,1.11e-30,9.03e-30,6.66e-29,4.51e-28,2.81e-27,1.62e-26,8.72e-26,4.38e-25]
I have used UnivariateSpline before in order to interpolate between data points and give a constant values outside of the given data range. However, when I try and use it this time for this data, I get this:
Does anyone know how I can get a desired interpolated function for this data, to the requirements described previously?
My current code is given below:
import numpy as np
from scipy.interpolate import interp1d
from scipy import interp
from scipy.interpolate import UnivariateSpline
import matplotlib.pyplot as plt
temp_vp = [280.0,290.0,300.0,310.0,320.0,330.0,340.0,350.0,360.0,370.0,380.0,390.0,400.0,410.0,420.0,430.0,440.0,450.0,460.0,470.0,480.0,490.0,500.0]
vp_in = [3.88e-52,5.16e-50,4.95e-48,3.53e-46,1.93e-44,8.26e-43,2.83e-41,7.93e-40,1.85e-38,3.62e-37,6.07e-36,8.79e-35,1.11e-33,1.25e-32,1.24e-31,1.11e-30,9.03e-30,6.66e-29,4.51e-28,2.81e-27,1.62e-26,8.72e-26,4.38e-25]
tempspace = np.linspace(200,10000,10000)
vp_f = UnivariateSpline(temp_vp, vp_in, k = 1, ext = 3)
fig=plt.figure(figsize=(4.5,3.6))
ax=fig.add_subplot(1,1,1)
ax.minorticks_on() # enable minor ticks
ax.set_axisbelow(True) # put grid behind curves
ax.grid(b=True, which='major', color='black', linestyle='-', zorder=1, linewidth=0.4, alpha = 0.12) # turn on major grid
ax.grid(b=True, which='minor', color='black', linestyle='-', zorder=1, linewidth=0.4, alpha = 0.12) # turn on minor grid
ax.scatter(temp_vp,vp_in, color = 'black', label = 'data', s= 5, zorder = 3)
ax.plot(tempspace, vp_f(tempspace), color = 'blue', label = 'Fit', zorder = 2)
ax.set_yscale('log')
ax.set_xscale('log')
ax.set_xlabel('Temperature [K]')
ax.set_ylabel('Vapor Pressure [Pa]')
ax.legend(labelspacing=0.25, fontsize = 8)
plt.xlim([250,600])
#plt.ylim([1e-10,1e5])
plt.savefig('Al_vpdata.pdf', bbox_inches='tight', format='pdf')
plt.savefig('Al_vpdata.png', dpi=300, bbox_inches='tight', format='png')
Are you really measuring pressures of 1e-50 Pa?
You are probably having underflow errors.
If you multiply vp_in by 1e52 you get:

Two colorbars on two subplots, same figure

I am trying to make a matplotlib plot with two subplots, and one colorbar to the right of each subplot. Here is my code currently:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from mpl_toolkits.axes_grid1 import make_axes_locatable
X = tsne_out[:,0]
Y = tsne_out[:,1]
Z = tsne_out[:,2]
fig = plt.figure(figsize = (20,15))
ax1 = fig.add_subplot(221)
ax1.scatter(X, Y, c = material, s = df['Diameter (nm)']/4, cmap = plt.get_cmap('nipy_spectral', 11))
ax1.set_title("2D Representation", fontsize = 18)
ax1.set_xlabel("TSNE1", fontsize = 14)
ax1.set_ylabel("TSNE2", fontsize = 14)
ax1.set_xlim(-20,20)
ax1.set_ylim(-20,20)
ax1.set_xticks(list(range(-20,21,10)))
ax1.set_yticks(list(range(-20,21,10)))
cbar = fig.colorbar(cax, ticks=list(range(0,9)))
cbar.ax.tick_params(labelsize=15)
cbar.ax.set_yticklabels(custom_ticks) # horizontal colorbar
ax2 = fig.add_subplot(222, projection='3d')
ax2.scatter(X, Y, Z, c = material, s = df['Diameter (nm)']/4, cmap = plt.get_cmap('nipy_spectral', 11))
ax2.set_title("3D Representation", fontsize = 18)
ax2.set_xlabel("TSNE1", fontsize = 14)
ax2.set_ylabel("TSNE2", fontsize = 14)
ax2.set_zlabel("TSNE3", fontsize = 14)
ax2.set_xlim(-20,20)
ax2.set_ylim(-20,20)
ax2.set_zlim(-20,20)
ax2.set_xticks(list(range(-20,21,10)))
ax2.set_yticks(list(range(-20,21,10)))
ax2.set_zticks(list(range(-20,21,10)))
cbar = fig.colorbar(cax, ticks = list(range(0,9)))
cbar.ax.tick_params(labelsize=15)
cbar.ax.set_yticklabels(custom_ticks)
This provides the following figure:
My question is: why does the first colorbar not show my custom ticks and how do I fix this?
The issue seems to be that ScalarMappable objects seem to be able to have at most one colorbar associated with them. When you draw the second colorbar with the same ScalarMappable, the original colorbar is unlinked and the previous settings are lost for the first colorbar.
Your code is missing some details (in particular, the definition of cax), so you either have to create two separate mappables, or directly use what each scatter call gives you. Furthermore, I'd be explicit about where you want to get your colorbars to be inserted.
An example fix, assuming that cax was really meant to refer to your scatter plots:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
X = np.random.rand(100) * 40 - 20
Y = np.random.rand(100) * 40 - 20
Z = np.random.rand(100) * 40 - 20
C = np.random.randint(1,8,100)
custom_ticks = list('ABCDEFGH')
fig = plt.figure(figsize = (20,15))
ax1 = fig.add_subplot(121)
sc1 = ax1.scatter(X, Y, c = C, cmap='viridis') # use this mappable
ax1.set_title("2D Representation", fontsize = 18)
ax1.set_xlabel("TSNE1", fontsize = 14)
ax1.set_ylabel("TSNE2", fontsize = 14)
ax1.set_xlim(-20,20)
ax1.set_ylim(-20,20)
ax1.set_xticks(list(range(-20,21,10)))
ax1.set_yticks(list(range(-20,21,10)))
cbar = fig.colorbar(sc1, ax=ax1, ticks=list(range(0,9))) # be explicit about ax1
cbar.ax.tick_params(labelsize=15)
cbar.ax.set_yticklabels(custom_ticks)
ax2 = fig.add_subplot(122, projection='3d')
sc2 = ax2.scatter(X, Y, Z, c=C, cmap='viridis') # next time use this one
ax2.set_title("3D Representation", fontsize = 18)
ax2.set_xlabel("TSNE1", fontsize = 14)
ax2.set_ylabel("TSNE2", fontsize = 14)
ax2.set_zlabel("TSNE3", fontsize = 14)
ax2.set_xlim(-20,20)
ax2.set_ylim(-20,20)
ax2.set_zlim(-20,20)
ax2.set_xticks(list(range(-20,21,10)))
ax2.set_yticks(list(range(-20,21,10)))
ax2.set_zticks(list(range(-20,21,10)))
cbar = fig.colorbar(sc2, ax=ax2, ticks=list(range(0,9))) # sc1 here is the bug
cbar.ax.tick_params(labelsize=15)
cbar.ax.set_yticklabels(custom_ticks)
plt.show()
This produces the following:
Note that I created an MCVE for you, and I simplified a few things, for instance the number of subplots. The point is that the colorbar settings stick now that they use separate mappables.
Another option is to create your colorbars first (using the same ScalarMappable if you want to), then customize both afterwards:
sc = ax1.scatter(X, Y, c = C, cmap='viridis')
cbar1 = fig.colorbar(sc, ax=ax1, ticks=np.arange(0,9))
ax2.scatter(X, Y, Z, c=C, cmap='viridis')
cbar2 = fig.colorbar(sc, ax=ax2, ticks=np.arange(0,9)) # sc here too
for cbar in cbar1,cbar2:
cbar.ax.tick_params(labelsize=15)
cbar.ax.set_yticklabels(custom_ticks)
The fact that the above works may suggest that the original behaviour is a bug.

How to obtain correct size for a second colorbar in matplotlib plot?

I wish to create a "split plot", i.e. to use different colormaps in the left and the right half of my plot. Accordingly I will need two different colorbars. Unfortunately I have to set the position of the second colorbar by hand and modify everytime a label or title is included. Is there a way to automatise that?
I wondered if I could extract the rect parameter of the following minimal example from the right colorbar. That would help me as I only had shift it a bit. Any other (/better) idea is also welcome.
At the moment, whenever I change the labels or title a bit the manually set position of the left colorbar has to be modified again. This is very annoying. I include a running minimal example and a the output it produces:
import matplotlib as mpl
params = {
'xtick.direction' : 'out',
'ytick.direction' : 'out',
'text.usetex' : True,
}
mpl.rcParams.update(params)
mpl.rcParams.update({'figure.autolayout': True})
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
extent_arr1 = [-1,0, -1,1]
extent_arr2 = [ 0,1, -1,1]
M = 501
# define test-data
data_arr1 = np.zeros((M, M))
data_arr2 = np.ones((M, M))
# define figure
fig = plt.figure()
ax = fig.add_subplot(111)
# left plot:
image1 = ax.imshow( data_arr1, cmap='jet', interpolation='bilinear', extent=extent_arr1, \
origin='lower')
plt.title("Minimal example")
cbar1 = plt.colorbar(image1)
# right plot:
image2 = ax.imshow( data_arr2, cmap='gnuplot', interpolation='bilinear', extent=extent_arr2, \
origin='lower')
# define axes-labels:
plt.xlabel(r"$x$")
plt.ylabel(r"$y$")
# define colour-bar at left side:
rect_loc = [0.0, 0.08, 0.03, 0.88] # define position ---> how to automatise this?
cax2 = fig.add_axes(rect_loc) # left | bottom | width | height
cbar2 = plt.colorbar(image2, cax=cax2)
cbar2.ax.yaxis.set_ticks_position('left')
# set limits:
ax.set_xlim(-1,1)
ax.set_ylim(-1,1)
plt.show()
output:
Thanks in advance!
There are of course several ways to create a colorbar axes and put it next to a plot. I would recommend reading those questions:
positioning the colorbar
Matplotlib 2 Subplots, 1 Colorbar
Many of those concepts can be extended to a second colorbar. The solution I would personally prefer is the following, which uses an axes divider. The advantage is that the colorbar keeps the size of the axes.
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np; np.random.seed(1)
plt.rcParams.update({'figure.autolayout': True})
fig, ax = plt.subplots(figsize=(6,4))
im = ax.imshow(np.random.rand(10,10), extent=[-1,0,0,1], cmap="RdYlGn")
im2 = ax.imshow(np.random.rand(10,10), extent=[0,1,0,1], cmap="magma")
ax.set_xlabel("x label")
ax.set_ylabel("y label")
ax.set_xlim(-1,1)
ax.set_ylim(0,1)
divider = make_axes_locatable(ax)
cax = divider.new_horizontal(size="5%", pad=0.2)
fig.add_axes(cax)
fig.colorbar(im2, cax=cax)
cax2 = divider.new_horizontal(size="5%", pad=0.7, pack_start=True)
fig.add_axes(cax2)
cb2 = fig.colorbar(im, cax=cax2)
cb2.ax.yaxis.set_ticks_position('left')
plt.show()

Colorbar tick labels as log outputs

I am playing around with histogram2d and I am trying incorporate a color bar logarithmic values.
Here is my current code:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.colors import LinearSegmentedColormap
cmap = LinearSegmentedColormap.from_list('mycmap', ['black', 'maroon',
'crimson', 'orange', 'white'])
fig = plt.figure()
ax = fig.add_subplot(111)
H = ax.hist2d(gas_pos[:,0]/0.7, gas_pos[:,1]/0.7, cmap=cmap,
norm=matplotlib.colors.LogNorm(), bins=350, weights=np.log(gas_Temp))
ax.tick_params(axis=u'both', which=u'both',length=0)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
cb = fig.colorbar(H[3], ax=ax, shrink=0.8, pad=0.01,
orientation="horizontal", label=r'$\log T\ [\mathrm{K}]$')
cb.ax.set_xticklabels([1,2,3,4])
cb.update_ticks()
empty = Rectangle((0,0 ), 0, 0, alpha=0.0)
redshift = fig.legend([empty], [r'$z = 127$'],
loc='upper right', frameon=False, handlelength=0, handletextpad=0)
redshift.get_texts()[0].set_color('white')
#fig.add_artist(redshift)
plt.show()
The weights are values not passed through np.log() and are currently being normalized through LogNorm().
What I am trying to get is to have the colorbar tic labels to be the logarithmic values of what is currently there eg. 10**4 --> 4, 10**6 --> 6, etc.
I have tried changing the formatting and also passing through the logarithmic values of np.log(gas_Temp), but nothing is really working.
The idiomatic thing to do is use a LogFormatterExponent to do the formatting of your colorbar. That's exactly what you need: to display 10**x values as x, or in other words, to display y values as log10(x).
Proof using dummy data:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
from matplotlib.ticker import LogFormatterExponent # <-- one new import here
# generate dummy data
histdata = 10**(np.random.rand(200,200)*4 + 1) # 10^1 -> 10^5
# plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.tick_params(axis=u'both', which=u'both',length=0)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
im = plt.imshow(histdata,cmap='viridis',norm=LogNorm())
cb = fig.colorbar(im, ax=ax, shrink=0.8, pad=0.01,
orientation="horizontal", label=r'$\log T\ [\mathrm{K}]$')
# v-- one new line here
cb.formatter = LogFormatterExponent(base=10) # 10 is the default
cb.update_ticks()
Compare the result of your original (left) with the modified version (right):

Matplotlib: Add colorbar to non-mappable object

I have a series of lines representing the change of a variable; each with a unique color. For that reason I want to add a colorbar next to the plot. The desired output is shown below.
The problem is that plot is a non-mappable object, i.e. the colorbar has to be added manually. I consider my current solution (below) sub-optimal as it involves size parameters of which I have no interest in controlling. I'd prefer a similar solution as for a mappable object (example below current solution).
Desired output
Current solution
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
x = np.linspace(0, 5, 100)
N = 20
cmap = plt.get_cmap('jet',N)
fig = plt.figure(figsize=(8,6))
ax1 = fig.add_axes([0.10,0.10,0.70,0.85])
for i,n in enumerate(np.linspace(0,2,N)):
y = np.sin(x)*x**n
ax1.plot(x,y,c=cmap(i))
plt.xlabel('x')
plt.ylabel('y')
ax2 = fig.add_axes([0.85,0.10,0.05,0.85])
norm = mpl.colors.Normalize(vmin=0,vmax=2)
cb1 = mpl.colorbar.ColorbarBase(ax2,cmap=cmap,norm=norm,orientation='vertical')
plt.show()
Desired solution
(obviously replacing imshow)
fig,ax = plt.subplots()
cax = ax.imshow(..)
cbar = fig.colorbar(cax,aspect=10)
plt.show()
You may define your own ScalarMappable and use it just as if it was present in the plot.
(Note that I changed the numbero f colors to 21 to have nice spacings of 0.1)
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
x = np.linspace(0, 5, 100)
N = 21
cmap = plt.get_cmap('jet',N)
fig = plt.figure(figsize=(8,6))
ax1 = fig.add_axes([0.10,0.10,0.70,0.85])
for i,n in enumerate(np.linspace(0,2,N)):
y = np.sin(x)*x**n
ax1.plot(x,y,c=cmap(i))
plt.xlabel('x')
plt.ylabel('y')
norm = mpl.colors.Normalize(vmin=0,vmax=2)
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
plt.colorbar(sm, ticks=np.linspace(0,2,N),
boundaries=np.arange(-0.05,2.1,.1))
plt.show()

Categories

Resources