I'm working with broken_barh plots. Is there any way to get a fixed height of a single broken_barh? The image should get bigger vertically, but proportions should stay the same.
Here is a simple example.
import matplotlib.pyplot as plt
import matplotlib as mlp
fig = plt.figure()
ax = fig.add_subplot(111)
broken_barh(self, xranges, yrange, **kwargs)
ax.broken_barh([(110, 30), (150, 10)], (0, 10), facecolors='blue')
ax.broken_barh([(10, 50), (100, 20), (130, 10)] , (10, 10),
facecolors=('red', 'yellow', 'green'))
ax.broken_barh([(50, 30), (85, 10)], (20, 10), facecolors='black')
ax.set_xlim(0,200)
ax.set_xlabel('seconds since start')
ax.set_yticks([0,10,20])
ax.set_yticklabels(['Bill', 'Jim', 'Jeff'])
ax.grid(True)
plt.savefig('broken_barh_example.png', bbox_inches='tight')
plt.show()
If I generate two plots, one with two broken_barh and the other with three, it looks like this:
with 2 broken_barh
http://imageshack.us/a/img195/747/brokenbarhexample2.png
with 3 broken_barh
http://img341.imageshack.us/img341/5650/brokenbarhexamplenoyran.png
The render fits everything into the available space. If you want the size of the figure to grow as you add more rows, you can do it by hand via
fig.set_size_inches(w, h * num_rows, forward=True)
to force a fixed bar height.
(doc)
Related
I am struggling with plotting the following dataset (image below). The dataset represents 10 rectangular features in 3D space. Those features are spaced at a distance of 3 cells in the Y axis. The X and Z columns present the range (number of cells) in the X and Z axes. The output should be 10 rectangles spaced at every 3 cells in Y direction. The rectangles can be in any color.
Another piece of infomraiton (not sure if it's relevent), the number of cells in X, Y, Z directions are 50 cells. Each cell represents a 100 ft distance in real life.
I tired numpy.meshgrid, but with no success.
First of all you need to get the corner points of your rectangles - this is fairly straight forward - it's just the 4 combinations of the 2 (x, z) corners, with all of the points having the y-value shown.
The rectangles can then be plotted as:
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import matplotlib.pyplot as plt
# Corner points of rectangles
feat1 = [(7,6,10),
(7, 6, 20),
(13, 6, 20),
(13, 6, 10)]
feat2 = [(2,9,13),
(2, 9, 17),
(18, 9, 17),
(18, 9, 13)]
feat3 = [(7,12,10),
(7, 12, 20),
(13, 12, 20),
(13, 12, 10)]
features = [feat1, feat2, feat3]
fig = plt.figure()
ax = Axes3D(fig)
facets = Poly3DCollection(features)
facets.set_facecolor(['blue', 'green', 'red'])
ax.add_collection3d(facets)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.show()
Which returns a plot like:
Ive been struggling with this for a while and figured it was time to come here. Essentially I have two subplots being graphed and they're totally fine except for one thing, the x axis. For some reason one subplot's x-axis is coming out perfectly and the other's is not.
Here is my Code:
## BAR PLOTS
#expected value vs probability of choosing option1
fig,ax = plt.subplots(1, 2, dpi=320)
data.plot(kind='bar', y='value_1', ax=ax[0], color ='red')
data.plot(kind='bar', y='p_1', ax=ax[1], color ='blue')
#ax.set_xlabel("Trials")
#ax.set_ylabel("Value 1 / P_1")
#plt.xticks(np.arange(0, len('value_1')+1, 5), np.arange(0, len('value_1')+1, 5) )
#ticks = range(0, 500, 5)
#labels = ticks
#plt.xticks(ticks, labels)
plt.xticks(np.arange(0, len(data.value_1)+1, 5), np.arange(0, len(data.value_1)+1, 5) )
# plt.xticks(np.arange(0, len(data.p_1)+1, 5), np.arange(0, len(data.p_1)+1, 5) )
#ax.legend(["Value 1, P_1"])
plt.title(' Expected Vs. Probability')
fig.savefig("figure.pdf")
plt.show()
Here is the output:
Try using set_xticks for each ax array:
ax[0].set_xticks(np.arange(0, len(data.value_1)+1, 5))
ax[1].set_xticks(np.arange(0, len(data.value_1)+1, 5))
As you did not provide data I cannot check this, but in principle the set_xticks should work per ax array.
I am plotting several heatmaps in matplotlib as shown below.
Here is my loop:
with open(gene_peak) as f:
count = 1
for line in f:
np_array=[]
gene_peak = line.strip().split("\t")
gene_id = gene_peak[0]
peaks = gene_peak[1].split(",")
for peak in peaks:
np_array.append(enhancer_fc[peak])
data, pval = stats.spearmanr(np.transpose(np.array(np_array)))
plt.subplot(4,3,count+1)
# plt.title(gene_id)
plt.pcolor(data, cmap=plt.cm.OrRd, vmin=-1, vmax=1)
plt.gca().invert_yaxis()
plt.gca().set_aspect(aspect='equal', adjustable='box-forced')
plt.xticks([])
plt.yticks([])
print count
count += 1
plt.show()
I am plotting the spearman correlations of different 2D arrays of different dimensions.
Question:
There are correlation values, so they range from -1 to 1. I want to add custom colorbar() such that values above 0.4 starts showing a gradient of red and below -0.4 shows a gradient of blue, such that I show only the points that are more than 0.4 and less than -0.4.
Also I would like to plot only one colorbar() such that the image looks cleaner. Any help would be appreciated, Thanks.
You can define your own discrete colormap using the ListedColorMap from Matplotlib. You can use the colorbar from one of the plots, and place it in position so it represent all of the plots visually. Here is an example with the colours you have given:
from matplotlib import colors
discrete_colors = [(255, 0, 20), (255, 70, 65), (255, 128, 110), (255, 181, 165), (64, 64, 64),
(0, 0, 0), (64, 64, 64), (124, 128, 217), (102, 107, 216), (69, 76, 215), (33, 33, 245)]
discrete_colors = [(r/255., g/255., b/255.) for r, g, b in discrete_colors]
my_colormap = colors.ListedColormap(discrete_colors)
subplot(211)
data = 2 * np.random.rand(10, 10) - 1.0
pcolor(data, cmap=my_colormap, vmin=-1, vmax=1)
subplot(212) # Some other plot
data = 2 * np.random.rand(10, 10) - 1.0
pc = pcolor(data, cmap=my_colormap, vmin=-1, vmax=1)
fig = gcf()
fig.subplots_adjust(right=0.70)
cax = fig.add_axes([0.80, 0.15, 0.05, 0.7])
fig.colorbar(pc, cax=cax)
You might have to adjust the code a bit. I'm using IPython 2.7.
I've just discovered the matplotlib path functionality and I'm using it with path.contains_point to check whether points are found within a region defined by 2 bezier curves.
I'm getting some unexpected behaviour where contains_point is returning True when I would have expected it to return False. Specifically, if the point to be tested is to the left of the region then it seems to be incorrect. On the right is ok.
Defining my paths as a number of straight lines rather than curves seems to work as expected.
A failing test case is as follows:
import matplotlib
import matplotlib.path as mplPath
import matplotlib.patches as patches
import matplotlib.pyplot as plt
import pylab
import pandas as pd
print "MPL Version {}".format(matplotlib.__version__) #1.5.0
print "MPL NP Version {}".format(matplotlib.__version__numpy__) #1.6
path_data = [
(mplPath.Path.MOVETO, (2, 10)),
(mplPath.Path.CURVE4, (0, 100)),
(mplPath.Path.CURVE4, (20, 100)),
(mplPath.Path.CURVE4, (40, 150)),
(mplPath.Path.MOVETO, (40, 150)),
(mplPath.Path.CURVE4, (42, 45)),
(mplPath.Path.CURVE4, (20, 30)),
(mplPath.Path.CURVE4, (2, 10))
]
codes, verts = zip(*path_data)
path = mplPath.Path(verts, codes)
patch = patches.PathPatch(path, facecolor='r', alpha=0.5)
#Plot the patch and a some of the test points to visualise
fig = plt.figure()
ax = fig.add_subplot(111)
ax.add_patch(patch)
ax.set_xlim(0, 50)
ax.set_ylim(0, 200)
ax.scatter(1, 50)
ax.scatter(20, 120)
ax.scatter(20, 25)
print path.contains_point((1,50)) #This should be false but is actually true
print path.contains_point((20,120)) #This should be false but is actually true
print path.contains_point((20, 25)) #This should be false and it is
plt.show()
Thanks in advance for any help you can provide. Python version is 2.7, Anaconda Distro on Linux Mint 17.3
Jim
You have an open path (extra moveto command). Once you comment it out, it works fine.
path_data = [
(mplPath.Path.MOVETO, (2, 10)),
(mplPath.Path.CURVE4, (0, 100)),
(mplPath.Path.CURVE4, (20, 100)),
(mplPath.Path.CURVE4, (40, 150)),
# (mplPath.Path.MOVETO, (40, 150)),
(mplPath.Path.CURVE4, (42, 45)),
(mplPath.Path.CURVE4, (20, 30)),
(mplPath.Path.CURVE4, (2, 10))
]
I am trying something like this:
vol_grid = MultipleLocator(1000)
fig_vol = plt.subplot2grid((count, count), (i, 0), rowspan=1, colspan=count)
fig_vol.yaxis.set_major_locator(vol_grid)
but it has no effect. Any ideas?
My intention is to set the labels on the y-axis 1000 units apart, i.e. have labels at 1000, 2000, 3000, etc.
You haven't plotted anything, and thats is why the tick labels are not showing (the ylim defaults to (0,1), you can set vol_grid = MultipleLocator(0.1) to see that)
from matplotlib.ticker import MultipleLocator
import matplotlib.pyplot as plt
vol_grid = MultipleLocator(1000)
fig_vol = plt.subplot2grid((2, 2), (0, 0), rowspan=1, colspan=2)
fig_vol.yaxis.set_major_locator(vol_grid)
We can change the ylim or just plot some data:
fig_vol.set_ylim(1000, 9000)
#plt.plot([1,2,3], [1000, 2000, 5000])