I am using imshow() in matplotlib like so:
import numpy as np
import matplotlib.pyplot as plt
mat = '''SOME MATRIX'''
plt.imshow(mat, origin="lower", cmap='gray', interpolation='nearest')
plt.show()
How do I add a legend showing the numeric value for the different shades of gray. Sadly, my googling has not uncovered an answer :(
Thank you in advance for the help.
Vince
Simple, just plt.colorbar():
import numpy as np
import matplotlib.pyplot as plt
mat = np.random.random((10,10))
plt.imshow(mat, origin="lower", cmap='gray', interpolation='nearest')
plt.colorbar()
plt.show()
There's a builtin colorbar() function in pyplot. Here's an example using subplots:
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
plot = ax.pcolor(data)
fig.colorbar(plot)
As usual, I figure it out right after I ask it ;). For posterity, here's my stab at it:
m = np.zeros((1,20))
for i in range(20):
m[0,i] = (i*5)/100.0
print m
plt.imshow(m, cmap='gray', aspect=2)
plt.yticks(np.arange(0))
plt.xticks(np.arange(0,25,5), [0,25,50,75,100])
plt.show()
I'm sure there exists a more elegant solution.
Vince
Related
Using this code, I don't know how to customize the colorbar. The colormaps on this webiste can't satisfy me.
shade = m.contourf(Lon,Lat,TBB,np.arange(-90, -20, 10),extend='both',cmap=plt.cm.get_cmap('jet'))
m.colorbar(shade)
I want to draw a picture like this with obvious colorbar. So, what should I do?
You can define your own colormap using matplotlib.colors.LinearSegmentedColormap() or matplotlib.colors.ListedColormap() and use it for your plot.
Example:
import numpy as np; np.random.seed(0)
import matplotlib.pyplot as plt
import matplotlib.colors
x = np.arange(0,25)
a = np.random.randint(0,130, size=(25,25))-115
a = np.sort(a).reshape(25,25)
colors = ["#eaa941", "#efef39", "#53a447", "#3b387f", "#48a2ba"]
cmap= matplotlib.colors.ListedColormap(colors)
cmap.set_under("crimson")
cmap.set_over("w")
norm= matplotlib.colors.Normalize(vmin=-100,vmax=-0)
fig, ax = plt.subplots()
im = ax.contourf(x,x,a, levels=[-100,-80,-60,-40,-20,0],
extend='both',cmap=cmap, norm=norm)
fig.colorbar(im, extend="both")
plt.show()
Looks a lot like the spectral colormap, which is given on the matplotlib page..
I have the following example code:
import numpy as np
import matplotlib.pyplot as plt
import random
data_theta = range(10,171,10)
data_theta_rad = []
for i in data_theta:
data_theta_rad.append(float(i)*np.pi/180.0)
data_r = random.sample(range(70, 90), 17)
print data_theta
print data_r
ax = plt.subplot(111, polar=True)
ax.plot(data_theta_rad, data_r, color='r', linewidth=3)
ax.set_rmax(95)
# ax.set_rmin(70.0)
ax.grid(True)
ax.set_title("Example", va='bottom')
plt.show()
...which produces something like this:
...but I would like to set theta=0 to the 'West'. So something like:
Any ideas how to do this with matplotlib (I made the pic below in powerpoint) ?
Simply use:
ax.set_theta_zero_location("W")
More info in the documentation of matplotlib.
A more flexible way:
ax.set_theta_offset(pi)
You can rotate the axis arbitrarily, just replace pi with the angle you want.
I have a 2D matrix I want to plot. The plotting itself works, but I need
a colorbar with it. The figure only makes sense when the data is
log-tranformed. And I want the colorbar show the original values. How
do I do this?
A search provided
A logarithmic colorbar in matplotlib scatter plot
but I cannot make this work.
The code below gives an idea of what I attempt to do. Only the revevant
lines are included (as far as I could see).
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
my_speed=np.ones(shape=(no,no))
fig=plt.figure(2)
ax=fig.add_subplot(1,1,1)
my_speed=np.log10(my_speed)
ax.imshow(my_speed, interpolation='bilinear', cmap=cm.jet)
plt.colorbar() #this does not work
plt.savefig('myspeedplot.png')
plt.close(2)
Thank you for any help
The idea is not to transform your data, but let the visualization do the trick for you.
pylot.imshow[1] has an optional parameter norm that can do the log transformation for you.
my_speed=np.ones(shape=(no,no))
fig = plt.figure(2)
ax = fig.add_subplot(1,1,1)
# my_speed=np.log10(my_speed)
img = ax.imshow(my_speed, interpolation='bilinear', cmap=cm.jet,
norm=mpl.colors.LogNorm())
fig.colorbar(img)
As far as I see, there are two problems with your code.
First, you are trying to have the ticks on colorbar show original values. For this you should not transform the data, but just normalize the plot.
And second, you are using the ax.imshow and this is why the colorbar does not see it. You should use plt.imshow or use im=ax.imshow and then colorbar(im)
Here is a working solution:
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
my_speed = np.random.rand(20, 20)
fig = plt.figure(2)
ax = fig.add_subplot(1, 1, 1)
im = ax.imshow(my_speed, interpolation='bilinear',
norm=mpl.colors.LogNorm(),
cmap=plt.cm.jet)
cb = plt.colorbar(im, orientation='vertical')
plt.show()
I'm working with data that has the data has 3 plotting parameters: x,y,c. How do you create a custom color value for a scatter plot?
Extending this example I'm trying to do:
import matplotlib
import matplotlib.pyplot as plt
cm = matplotlib.cm.get_cmap('RdYlBu')
colors=[cm(1.*i/20) for i in range(20)]
xy = range(20)
plt.subplot(111)
colorlist=[colors[x/2] for x in xy] #actually some other non-linear relationship
plt.scatter(xy, xy, c=colorlist, s=35, vmin=0, vmax=20)
plt.colorbar()
plt.show()
but the result is TypeError: You must first set_array for mappable
From the matplotlib docs on scatter 1:
cmap is only used if c is an array of floats
So colorlist needs to be a list of floats rather than a list of tuples as you have it now.
plt.colorbar() wants a mappable object, like the CircleCollection that plt.scatter() returns.
vmin and vmax can then control the limits of your colorbar. Things outside vmin/vmax get the colors of the endpoints.
How does this work for you?
import matplotlib.pyplot as plt
cm = plt.cm.get_cmap('RdYlBu')
xy = range(20)
z = xy
sc = plt.scatter(xy, xy, c=z, vmin=0, vmax=20, s=35, cmap=cm)
plt.colorbar(sc)
plt.show()
Here is the OOP way of adding a colorbar:
fig, ax = plt.subplots()
im = ax.scatter(x, y, c=c)
fig.colorbar(im, ax=ax)
If you're looking to scatter by two variables and color by the third, Altair can be a great choice.
Creating the dataset
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
df = pd.DataFrame(40*np.random.randn(10, 3), columns=['A', 'B','C'])
Altair plot
from altair import *
Chart(df).mark_circle().encode(x='A',y='B', color='C').configure_cell(width=200, height=150)
Plot
I'm using contourf in pyplot to plot some scalar data, but when my domain is non-square i feel like the data is misrepresented because it always plots it in a square (though the axis values will increase faster on one side.) How can i force the axis scaling to be equal, such that if my domain is twice as long in the x-direction the image is actually plotted in a rectangle with this property?
I'm doing something like this:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
contour = ax.contourf(X,Y,Z)
fig.colorbar(contour)
fig.canvas.draw()
Using ax.set_aspect:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111)
x=np.r_[-10:10:100j]
y=np.r_[-20:20:100j]
z= np.add.outer(x*x, y*y)
contour=ax.contour(x,y,z)
fig.colorbar(contour)
ax.set_aspect('equal')
# ax.axis('equal')
plt.show()
yields
while changing ax.set_aspect('equal') to
ax.axis('equal')
yields
This might help:
ax = fig.add_subplot(111, aspect="equal")
You need to change the axis setting:
axis('equal')
See all of the axis settings here:
http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.axis