Creating a color bar for a plot made with plt.fill

I am new to Python (I used to be an IDL user), so I hope that I ask for this in an understandable way. I am trying to create a polar graph with x number of boxes where the data in the bunker is averaged and the color associated with this value is set. This seems to work fine when using the plt.fill command, where I can define the cell and then the fill color. The problem arises when I try to make a colored strip for this. I keep getting errors pointing to the AttributeError attribute: The Figure object does not have the autoscale_None attribute

Any advice would be helpful.

import matplotlib.pyplot as plt import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt import matplotlib.cm as cm from matplotlib.pyplot import figure, show, rc, grid import pylab r = np.arange(50)/5. rstep = r[1] - r[0] theta = np.arange(50)/50.*2.*np.pi tstep = theta[1] - theta[0] colorv = np.arange(50)/50. # force square figure and square axes looks better for polar, IMO width, height = mpl.rcParams['figure.figsize'] size = min(width, height) # make a square figure fig = figure(figsize=(size, size)) ax = fig.add_axes([0.1, 0.1, .8, .8])#, polar=True) my_cmap = cm.jet for j in range(len(r)): rbox = np.array([r[j], r[j], r[j]+ rstep, r[j] + rstep]) for i in range(len(theta)): thetabox = np.array([theta[i], theta[i] + tstep, theta[i] + tstep, theta[i]]) x = rbox*np.cos(thetabox) y = rbox*np.sin(thetabox) plt.fill(x,y, facecolor = my_cmap(colorv[j])) # Add colorbar, make sure to specify tick locations to match desired ticklabels cbar = fig.colorbar(fig, ticks=[np.min(colorv), np.max(colorv)]) cb = plt.colorbar() plt.show() 

* here is a slightly better example of my real data, there are no holes everywhere, so in this example I just made a big quarter circle. When I tried to get stuck, the code seems to be trying to interpolate these areas.

 r = np.arange(50)/50.*7. + 3. rstep = r[1] - r[0] theta = np.arange(50)/50.*1.5*np.pi - np.pi tstep = theta[1] - theta[0] colorv = np.sin(r/10.*np.pi) # force square figure and square axes looks better for polar, IMO width, height = mpl.rcParams['figure.figsize'] size = min(width, height) # make a square figure fig = figure(figsize=(size, size)) ax = fig.add_axes([0.1, 0.1, .8, .8])#, polar=True) my_cmap = cm.jet for j in range(len(r)): rbox = np.array([r[j], r[j], r[j]+ rstep, r[j] + rstep]) for i in range(len(theta)): thetabox = np.array([theta[i], theta[i] + tstep, theta[i] + tstep, theta[i]]) x = rbox*np.cos(thetabox) y = rbox*np.sin(thetabox) plt.fill(x,y, facecolor = my_cmap(colorv[j])) # Add colorbar, make sure to specify tick locations to match desired ticklabels #cbar = fig.colorbar(fig, ticks=[np.min(colorv), np.max(colorv)]) #cb = plt.colorbar() plt.show() 

And then with the gear ...

from matplotlib.mlab import griddata p>

 r = np.arange(50)/5. rstep = r[1] - r[0] theta = np.arange(50)/50.*1.5*np.pi - np.pi tstep = theta[1] - theta[0] colorv = np.sin(r/10.*np.pi) # force square figure and square axes looks better for polar, IMO width, height = mpl.rcParams['figure.figsize'] size = min(width, height) # make a square figure fig = figure(figsize=(size, size)) ax = fig.add_axes([0.1, 0.1, .8, .8])#, polar=True) my_cmap = cm.jet x = r*np.cos(theta) y = r*np.sin(theta) X,Y = np.meshgrid(x,y) data = griddata(x,y,colorv,X,Y) cax = plt.contourf(X,Y, data) plt.colorbar() # Add colorbar, make sure to specify tick locations to match desired ticklabels #cbar = fig.colorbar(fig, ticks=[np.min(colorv), np.max(colorv)]) #cb = plt.colorbar() plt.show() 
+8
python matplotlib colorbar
source share
2 answers

So, I found a workaround. Since I know a region in which I definitely will not have data, I spoke there. I made sure that the data covers the whole spectrum of what I upload. Then I cover it (this area will still be closed, it shows where the "land" is). Now I can go and use plt.fill, as before, and use the color bar from randomly loaded data. I know this is not the right way, but it works and does not try to interpolate my data.

Thanks so much for helping sorting. and if you know a better way, I would be glad to hear that!

 hid = plt.pcolormesh(X,Y, data, antialiased=True) #here we cover up the region that we just plotted in r3 = [1 for i in range(360)] theta3 = np.arange(360)*np.pi/180. plt.fill(theta3, r3, 'w') #now we can go through and fill in all the regions for j in range(len(r)): rbox = np.array([r[j], r[j], r[j]+ rstep, r[j] + rstep]) for i in range(len(theta)): thetabox = np.array([theta[i], theta[i] + tstep, theta[i] + tstep, theta[i]]) x = rbox*np.cos(thetabox) y = rbox*np.sin(thetabox) colorv = np.sin(r[j]/10.*np.pi) plt.fill(thetabox,rbox, facecolor = my_cmap(colorv)) #And now we can plot the color bar that fits the data Tada :) plt.colorbar() plt.show() 

Output of above code

+1
source share

colorbar requires objects to be an instance of ScalarMappable to make them a color bar.

Since you manually install each slab, there is nothing that essentially has a color panel.

There are several ways to fake it from your color palette, but in this case a much simpler solution.

pcolormesh does exactly what you want and will be much faster.

As an example:

 import numpy as np import matplotlib.pyplot as plt # Linspace makes what you're doing _much_ easier (and includes endpoints) r = np.linspace(0, 10, 50) theta = np.linspace(0, 2*np.pi, 50) fig = plt.figure() ax = fig.add_subplot(111, projection='polar') # "Grid" r and theta into 2D arrays (see the docs for meshgrid) r, theta = np.meshgrid(r, theta) cax = ax.pcolormesh(theta, r, r, edgecolors='black', antialiased=True) # We could just call `plt.colorbar`, but I prefer to be more explicit # and pass in the artist that I want it to extract colors from. fig.colorbar(cax) plt.show() 

enter image description here

Or, if you prefer non-polar axes, as in your code example:

 import numpy as np import matplotlib.pyplot as plt r = np.linspace(0, 10, 50) theta = np.linspace(0, 2*np.pi, 50) # "Grid" r and theta and convert them to cartesian coords... r, theta = np.meshgrid(r, theta) x, y = r * np.cos(theta), r * np.sin(theta) fig = plt.figure() ax = fig.add_subplot(111) ax.axis('equal') cax = ax.pcolormesh(x, y, r, edgecolors='black', antialiased=True) fig.colorbar(cax) plt.show() 

enter image description here

Note. If you prefer the border lines to be slightly less dark, just specify linewidth=0.5 or something similar to pcolormesh .

Finally, if you want to directly make a color panel from the color code in the source code, you must create an instance of ScalarMappable from it and transfer it to the colorbar . It's easier than it sounds, but it's a bit verbose.

As an example, in your source code, if you do something like the following:

 cax = cm.ScalarMappable(cmap=my_cmap) cax.set_array(colorv) fig.colorbar(cax) 

He must do what you want.

+7
source share

All Articles