Matplotlib pie chart wedge transparency? - python

I saw that matplotlib's pyplot.scatter() has an 'alpha' parameter that can be used to set the transparency of points. The pyplot.pie() doesn't have a similar parameter however. How can I set the transparency of certain wedges?

I found the answer while writing up this question and figured I'd post the solution for anyone who wants to know.
To set a wedge to be transparent:
import matplotlib.pyplot as plt
x = [1,2,3,0.4,5]
alpha = 0.5
which_wedge = 4
n = plt.pie(x)
n[0][which_wedge].set_alpha(alpha)
If you want to only display a single wedge, use a loop:
for i in range(len(n[0])):
n[0][i].set_alpha(0.0)
n[0][which_wedge].set_alpha(1.0)
Hope this helps someone! It can probably be used for pyplot.bar() too to hide certain bars.

alpha can be passed to plt.pie directly using the wedgeprop arg (credit #Seth):
import matplotlib.pyplot as plt
plt.pie(x, wedgeprops={"alpha": 0.5})

Related

Matplotlib colorbar without offset notation [duplicate]

I am trying to put a colorbar to my image using matplotlib. The issue comes when I try to force the ticklabels to be written in scientific notation. How can I force the scientific notation (ie, 1x10^0, 2x10^0, ..., 1x10^2, and so on) in the ticks of the color bar?
Example, let's create and plot and image with its color bar:
import matplotlib as plot
import numpy as np
img = np.random.randn(300,300)
myplot = plt.imshow(img)
plt.colorbar(myplot)
plt.show()
When I do this, I get the following image:
However, I would like to see the ticklabels in scientific notation... Is there any one line command to do this? Otherwise, is there any hint out there? Thanks!
You could use colorbar's format parameter:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as ticker
img = np.random.randn(300,300)
myplot = plt.imshow(img)
def fmt(x, pos):
a, b = '{:.2e}'.format(x).split('e')
b = int(b)
return r'${} \times 10^{{{}}}$'.format(a, b)
plt.colorbar(myplot, format=ticker.FuncFormatter(fmt))
plt.show()
You can specify the format of the colorbar ticks as follows:
pl.colorbar(myplot, format='%.0e')
There is a more straightforward (but less customizable) way to get scientific notation in a ColorBar without the %.0e formatting.
Create your ColorBar:
cbar = plt.colorbar()
And call the formatter:
cbar.formatter.set_powerlimits((0, 0))
This will make the ColorBar use scientific notation. See the example figure below to see how the ColorBar will look.
The documentation for this function can be found here.
It seems that cbar.formatter.set_powerlimits((0,0)) alone in Joseph's answer does not render math format like $10^3$ yet.
Using further cbar.formatter.set_useMathText(True) gives something like $10^3$.
import matplotlib.pyplot as plt
import numpy as np
img = np.random.randn(300,300)*10**5
myplot = plt.imshow(img)
cbar = plt.colorbar(myplot)
cbar.formatter.set_powerlimits((0, 0))
# to get 10^3 instead of 1e3
cbar.formatter.set_useMathText(True)
plt.show()
generates
plot.
See the document of set_useMathText() here.
PS: Maybe this suits best for a comment. But I do not have enough reputations.

Manage and accumulate subplots in matplotlib

I have a function that produces triangles and quadrilaterals (called 'trisq') in red or green, resp. My goal is to make an arrangement of these shapes on the same plot by running a loop over my drawing function.
I can draw multiple shapes and call plt.show() on it which works fine but after that I won't be able to add more shapes as it gives me a blank output.
I think my issue is that I don't know how to control subplot command. Please see my inline comment in the code for how it goes wrong. What would be the cleanest way to do this? Thanks!
(Btw, this is my first time posting here. I think my question is basic but I hope that at least I've posed it in a clear way).
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
fig, ax = plt.subplots()
def trisq(points):
inf = 20
plt.xlim(-inf, inf)
plt.ylim(-inf, inf)
plt.gca().set_aspect('equal', adjustable='box')
ver = np.array(points)
polygon = Polygon(ver, True)
patches = []
patches.append(polygon)
if len(points) == 3:
color = 'red'
elif len(points) == 4:
color = 'green'
p = PatchCollection(patches, color = color,cmap=matplotlib.cm.jet, alpha=0.4)
ax.add_collection(p)
trisq([(4,18),(6,16),(5,-1),(-5,9)]
trisq([(4,-8),(1,7),(15,9)])
# this works as expected
plt.show()
trisq([(4,8),(12,3),(0,0),(1,9)])
# but this one returns a blank plot
plt.show()
Update:
My concrete question is: how do I show a graph, then add more elements to it and show it again in the above context and possibly repeat inside a loop? Apparently, plt.show() can only be called once and not in an ongoing manner.
Plt.show() shows the active figures. After your first call to plt.show() there is no active figure any more.
Unfortunately the question is not clear about what the actual goal is.
You may call plt.show only once at the end. You may also create a new figure in between.
Make sure to add the collection inside the trisq function.

On matplotlib logarithmic axes labels

Dear matplotlib community,
I have a very quick question regarding logarithmic axis labelling that I'm sure one of you could answer at the drop of a hat.
Essentially I have a log axis in matplotlib with labels of 10^-2, 10^-1, 10^0, 10^1, 10^2 etc
However, I would like 0.01, 0.1, 1, 10, 100.
Could anyone guide me on this. I have tried a few options, such as:
ax.set_xticks([0.01,0.1,1,10,100])
ax.set_xlabels([0.01,0.1,1,10,100])
Any pro tips would be greatly appreciated!
I think you want ax.xaxis.set_major_formatter(FormatStrFormatter("%g")), as in:
x=[0.1,1,10,100,1000]
y=[-1,0,1,2,3]
fig,ax=plt.subplots()
ax.plot(x,y,'.-')
ax.set_xscale('log')
ax.xaxis.set_major_formatter(FormatStrFormatter("%g"))
Example output:
A nice way is to use the FuncFormatter class of the matplotlib.ticker module. In conjunction with a custom function definition of your own making, this can help to customise your ticks to the exact way you want them. This particular bit of code works well with the logarithmic scale employed by matplotlib.
import numpy as np
import matplotlib.pylab as plt
x = np.linspace(-10,10)
y = np.exp(x)
plt.close('all')
fig,ax = plt.subplots(1,1)
ax.plot(x,y,'bo')
ax.set_yscale('log')
#Placed the import/function definitions here to emphasize
#the working lines of code for this particular task.
from matplotlib.ticker import FuncFormatter
def labeller(x, pos):
"""
x is the tick value, pos is the position. These args are needed by
FuncFormatter.
"""
if x < 1:
return '0.'+'0'*(abs(int(np.log10(x)))-1)+\
format(x/10**(np.floor(np.log10(x))),'.0f')
else:
return format(x,'.0f')
#FuncFormatter class instance defined from the function above
custom_formatter = FuncFormatter(labeller)
ax.yaxis.set_major_formatter(custom_formatter)
plt.show()
Result:
First, instead of set_xlabels you should call set_xticklabels for the actual tick labels. That said, at least in my current environment (python 2.7, matplotlib 1.4.3, OS X 10.10) that is not always enough. When doing instruction by instruction in a REPL (e.g. ipython) sometimes is necessary to update the axis after calling set_xticklabels. A quick hack to do that is to simply call grid(True) or grid(False). For example:
x = np.logspace(-2,2, 1000)
y = np.sin(x)
l = [0.01,0.1,1,10,100]
plt.semilogx(x,y)
plt.gca().set_xticks(l)
plt.gca().set_xticklabels(l)
plt.grid(True)
Empirical note: the grid(False) trick doesn't seem to be necessary when pasting that gist using ipython's %paste magic (anybody know why?)

2D Heat Map using matplot lib

I'm new to python please so bear with me:
I'v been tryin to plot a 2D Heat-Map, similar to the one shown here:
http://mips.helmholtz-muenchen.de/plant/static/images/A_thal_LTRs.png
using the contourf or the colorbar classes, but it just doesnt seem to work.
im using two very simple data-sets as showen in the code:
`
import numpy as np
import matplotlib.pyplot as plt
abundance = [0.2,0.3,0.25,0.05,0.05,0.04,0.06]
grain_size = [200,100,70,50,10,5,1]
`
i would like the grain_size array to be my x_axis (on a logarithmic scale) and my colors to represent the abundance corresponding with each grain_size (so 0.2 corresponds with 200, 0.3 corresponds with 100 etc...)
so i know i need to normalize my abundance array to fit to a color-bar, but then what?
thanks a lot!
Is this what you want ?
import matplotlib.cm as cm
ab = np.array(abundance)
gs = np.array(grain_size)
ab_norm = ab/ab.max()*100
plt.matshow([ab_norm], cmap=cm.gist_rainbow_r)
plt.xticks(range(7), gs)
plt.yticks(range(1), ["abundance"])
plt.colorbar()
plt.show()
You can change colormap by choosing another one, see here for some of them.
Tell me if it's not that, and if you don't understand something.
Hope this helps.

How to disable auto-swapping in axes labels in matplotlib?

Using matplotlib in Python I drew a 3D graph. When I rotate the graph I noticed that the axes labels swap automatically which does not look interesting or helping to me. In fact it disturbs my focusing on the purpose of rotation which is to explore visually the presented data.
Q: How to disable auto-swapping axes labels while rotating in matplotlib?
I grabbed some ideas from SO, examined many and finally developed the following solution. It simply works.
from __future__ import division
import scipy as sp
import mpl_toolkits.mplot3d as a3d
import pylab as pl
nan = sp.nan
def axesoff():
box = [[-1,1,1,-1,-1,1,1,-1,-1,-1,nan,1,1,nan,1,1,nan,-1,-1],
[-1,-1,-1,-1,1,1,1,1,-1,-1,nan,-1,1,nan,1,-1,nan,1,1],
[-1,-1,1,1,1,1,-1,-1,-1,1,nan,-1,-1,nan,1,1,nan,-1,1]]
ax3.plot(*box,color='k')
for axis in (ax3.w_xaxis,ax3.w_yaxis,ax3.w_zaxis):
for obj in axis.get_ticklines(): obj.set_visible(False)
axis.set_ticklabels('')
axis.line.set_visible(False)
axis.pane.set_visible(False)
ax3.grid(False)
ax3.axis('equal')
#------here we go
x,y,z = sp.random.uniform(low=-1,high=1,size=(3,1000))
c = (x+1)+(y+1)+(z+1)
s = c*10
ax3 = a3d.Axes3D(pl.figure())
ax3.scatter(x,y,z,lw=0,s=s,c=c,alpha=0.5)
axesoff()
pl.show()

Categories

Resources