Change markerfacecolor for some of the markers in Matplotlib - matplotlib

I have a plot that shows markers in a circle. I want to be able to change the colour of 3 of them. I've tried using a variable for markerfacecolor as follows but that doesn't work:
angle = 0.0
colorR = 'red'
angleUpdate = 2 * numpy.pi / (len(v.T))
for i in range(len(v.T)):
x = numpy.sin(angle)
y = numpy.cos(angle)
angle += angleUpdate
if i < 3:
colorR = 'green'
v[0, i] = x
v[1, i] = y
plt.plot(v[0], v[1], 'ko', markerfacecolor = colorR, markersize = 70, clip_on = False)
plt.show()
Is there a way of doing this?

In your plot 'ko' means put a black circle marker; k stands for black. You should try:
plt.plot(v[0], v[1], 'o', markerfacecolor = 'red')
To get the abbreviation of other symbols and colors try:
help(plt.plot)
You can either achieve your case using plot or scatter, depending on what you are doing:
import pylab as plt
x=[1,2,3,4,5,6,7,8,9,10]
plt.plot(x[:5],x[:5],'o',c='r',markersize=10)
plt.plot(x[5:],x[5:],'o',c='b',markersize=10)
plt.show()
will generate,
Similarly, you can also use
plt.scatter(x[:5],x[:5],c='r',s=100)
plt.scatter(x[5:],x[5:],c='b',s=100)

Related

How do I invert matplotlib bars at a specific point instead of when negative?

I'd like to invert the bars in this diagram when they are below 1, not when they are negative. Additionally I'd like to have even spacing between the ticks/steps on the y-axis
Here is my current code
import matplotlib.pyplot as plt
import numpy as np
labels = ['A','B','C']
Vals1 = [28.3232, 12.232, 9.6132]
Vals2 = [0.00456, 17.868, 13.453]
Vals3 = [0.0032, 1.234, 0.08214]
x = np.arange(len(labels))
width = 0.2
fig, ax = plt.subplots()
rects1 = ax.bar(x - width, Vals1, width, label='V1')
rects2 = ax.bar(x, Vals2, width, label='V2')
rects3 = ax.bar(x + width, Vals3, width, label='V3')
ax.set_xticks(x)
ax.set_xticklabels(labels)
plt.xticks(rotation=90)
ax.legend()
yScale = [0.0019531,0.0039063,0.0078125,0.015625,0.03125,0.0625,0.125,0.25,0.5,1,2,4,8,16,32]
ax.set_yticks(yScale)
plt.show()
I believe I've stumbled upon the answer, here it is for anyone else looking for the solution. Add the argument bottom='1' to ax.bar instantiation, and then flip the values in the array.
for i in range(len(Vals1)):
Vals1[i] = (1 - Vals1[i]) * -1
As you mentioned, the key is the bottom param of Axes.bar:
bottom (default: 0): The y coordinate(s) of the bars bases.
But beyond that, you can simplify your plotting code using pandas:
Put your data into a DataFrame:
import pandas as pd
df = pd.DataFrame({'V1': Vals1, 'V2': Vals2, 'V3': Vals3}, index=labels)
# V1 V2 V3
# A 28.3232 0.00456 0.00320
# B 12.2320 17.86800 1.23400
# C 9.6132 13.45300 0.08214
Then use DataFrame.sub to subtract the offset and DataFrame.plot.bar with the bottom param:
bottom = 1
ax = df.sub(bottom).plot.bar(bottom=bottom)

misalignment between grid cells and color mesh used to highlight them (in Matplotlib)

I am using the following code to to generate this heat map:
dim = np.arange(1, 32, 1)
fig, ax = plt.subplots(figsize=(7,9))
heatmap = ax.imshow(h, aspect=1, cmap=plt.cm.get_cmap('Blues', 5), clim=[0,100])
ax.set_ylabel("Days", fontsize=15)
ax.set_xlabel("Months", fontsize=15)
ax.set_title("Percentage of records per day", fontsize=18)
ax.set_yticks(range(0,31))
ax.set_yticklabels(dim, ha='center', minor=False)
ax.set_xticks(range(0,13,1))
ax.set_xticklabels(ylabel[7:],rotation=45, ha='right')
ax.grid(which = 'minor', color = 'w')
ax.set_facecolor('gray')
ax.xaxis.set_minor_locator(MultipleLocator(.5))
ax.yaxis.set_minor_locator(MultipleLocator(.5))
cbaxes = fig.add_axes([.8, .35, .04, .3])
cbar = fig.colorbar(heatmap, ticks = [0, 20, 40, 60, 80 ,100], label = 'Percentage', cax = cbaxes)
fig.show()
I would like to highlight all of the cells with a value greater or equal to 60.
I tried adding this to my code:
highlight = (h> 60)
highlight = np.ma.masked_less(highlight, 1)
ax.pcolormesh(highlight, facecolor = 'None')
and got this:
I am almost there but the cells and the mesh are misaligned. How could I fix this?
The cells in a heatmap are centered on integers, this means for example that the cell with index 0,0 is in fact -0.5 to 0.5 on both axes. You have to subtract 0.5 to the coordinates of your highlights.
Thanks to mozway's comment I was able to fix my problem. I changed the beginning of my code to:
highlight = (h> 60)
highlight = np.ma.masked_less(highlight, 1)
x = np.arange(-0.5,12,1) # len = 10
y = np.arange(-0.5,30,1) # len = 6
X, Y = np.meshgrid(x, y)
and change the line plotting the color mesh to:
ax.pcolormesh(x,y,highlight, facecolor = 'None', edgecolors = 'w',shading='auto', zorder=2)
I also had to set the z-order of the color mesh to be greater than the grid lines (zorder=2 and zorder=1 respectively).

Issue adjusting figsize with matplotlib barh subplot

I've tried specifying in a few ways but have not been able to get this figure any bigger than what's shown.
category_names = ['Database', 'Frontend', 'QA', 'ML', 'Fullstack']
labels = list(final_df.index)
data = np.array(final_df.iloc[:, 1:])
data_cum = data.cumsum(axis=1)
category_colors = plt.get_cmap('RdYlGn')(np.linspace(0, 1000, data.shape[1]))
fig, ax = plt.subplots(figsize=(100,75))
ax.invert_yaxis()
# ax.xaxis.set_visible(False)
ax.set_xlim(0, 200)
for i, (colname, color) in enumerate(zip(category_names, category_colors)):
widths = data[:, i]
starts = data_cum[:, i] - widths
ax.barh(labels, widths, left=starts, height=0.5,
label=colname, color=color)
xcenters = starts + widths / 2
r, g, b, _ = color
text_color = 'white' if r * g * b < 0.5 else 'darkgrey'
for y, (x, c) in enumerate(zip(xcenters, widths)):
ax.text(x, y, str(int(c)), ha='center', va='center',
color=text_color, fontsize=15)
If I make the figsize any bigger, the kernel dies and I've tried adjusting height and np.linspace params, as well as trying to set size with fig.set_size_inches. Any ideas on what's going on here?

Shapefile zooming to plot with geopandas

I have a shapefile of Italy and I'm plotting the GIS Data on it. Thing is I've got a small trajectory of a bus going within a city(Rome) and when i`m plotting, it appears like 1 dot. I guess because of my map.
How to zoom the map (.shp) ?
street_map = gpd.read_file("roads.shp")
...
...
fig,ax = plt.subplots(figsize = (20,15))
street_map.plot(ax = ax, alpha = 0.4, color = "grey")
geo_df[geo_df['Perc_'] > 25].plot(ax = ax, markersize = 20, color = "blue",
marker = "o", label = "Neg")
geo_df[geo_df['Perc_'] < 25].plot(ax = ax, markersize = 20, color = "red",
marker = "^", label = "Pos")
plt.legend(prop={'size':15})
Based on your 1st image, it is possible to get the zoom-in plot by specifying proper x and y limits.
...
ax.set_ylim([40.4, 47.2])
ax.set_xlim([7.0, 14.4])
(Place this code before plt.legend().
Hope this is useful.

Matplotlib: Scatterplot and heatmap in the same plot

I'm trying to do a scatterplot and heatmap in the same plot.
The scatterplot is as follows:
examples, targets = zip(*list(blue_data()))
examples2, targets2 = zip(*list(red_data()))
plt.plot(np.array(examples), np.array(targets), 'o', color = 'b')
plt.plot(np.array(examples2), np.array(targets2), 'o', color = 'r')
The above works just fine. I also want to do a heatmap. It works just fine, if I do it in a separate subplot. However, I want to try to do both on the same plot, sharing the same axes and am unsure how to do it. This is the code for the heatmap:
x = np.linspace(lower_x, upper_x, 100)
y = np.linspace(lower_y, upper_y, 100)
X, Y = np.meshgrid(x, y)
Z = np.zeros((x.size,y.size))
for ii in range(len(x)):
for jj in range(len(y)):
X_ = X[ii,jj];
Y_ = Y[ii,jj];
Z[ii,jj] = some_function(X_,Y_)
cmap = mpl.colors.ListedColormap(['r', 'b'])
bounds = [-100,0,100]
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
plt.imshow(Z,cmap= cmap, norm = norm, extent = [-lower_x,upper_x,-lower_y,upper_y], origin = 'lower');
How can I combine the two plots so that they appear on the same plot with aligned axes?