I am plotting a segmentation, and running into an issue where my categorical values are only showing up one color. Any advice?
[![fig = plt.figure(figsize = (20,10))
ax = fig.add_subplot(1,1,1)
ax.set_xlabel('Sentiment Score', fontsize = 15)
ax.set_ylabel('Star Review', fontsize = 15)
ax.set_title('Heinz Segmentation', fontsize = 20)
targets = \['Sugar/ Healthy Positives', 'Sugar/ Healthy Negatives', 'Price/ Value Positives', 'Price/ Value Negatives', 'Purists Positives', 'Purists Negatives'\]
colors = \['r', 'g', 'b', 'c', 'm', 'y'\]
for target, color in zip(targets,colors):
ax.scatter(df.Compound,df.StarsInt
, c = color
, s = 200
,alpha = .5)
ax.legend(targets, prop={'size': 14})
ax.grid()][1]][1]
IIUC, you have a problem in the legends. You forgot to pass the legend while plotting
for target, color in zip(targets,colors):
ax.scatter(df.Compound,df.StarsInt, c=color,
s = 200,alpha = .5,
label=target) # <--- pass the label to show in legend
Related
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).
I receive the error No handles with labels found to put in legend. when running the code below. How can I add a legend to this scatter plot that shows the color definitions (a red dot for A, blue dot for B, green dot for C)?
### Dummy Dataset
x = [0,1,-1,4,0,2,2,4,2]
y = [1,5,9,2,4,2,5,6,1]
cat = ['A','B','B','B','A','C','A','B','B']
df = pd.DataFrame(list(zip(x,y,cat)), columns =['x', 'y', 'cat'])
### Build color definitions
df.loc[:, 'color'] = df.cat
df.color.replace(['A', 'B', 'C'], ['red', 'blue', 'green'], inplace=True)
display(df)
### Plotting
fig = plt.figure(figsize=(5,5), constrained_layout=True)
gs = fig.add_gridspec(2, 1)
ax1 = fig.add_subplot(gs[0, 0])
ax1.scatter(df.x, df.y, edgecolors = 'none', c = df.color)
ax1.legend(loc='upper left', facecolor='white', frameon=1,
framealpha=1, labelspacing=0.2, borderpad=0.25)
It seems like there might not be a way to do this without a simple loop. Based on the procedure here, the following code works.
x = [0,1,-1,4,0,2,2,4,2]
y = [1,5,9,2,4,2,5,6,1]
cat = ['A','B','B','B','A','C','A','B','B']
df = pd.DataFrame(list(zip(x,y,cat)), columns =['x', 'y', 'cat'])
mycolorsdict = {'A':'red', 'B':'blue', 'C':'green'}
fig = plt.figure(figsize=(5,5), constrained_layout=True)
gs = fig.add_gridspec(2, 1)
ax1 = fig.add_subplot(gs[0, 0])
grouped = df.groupby('cat')
for key, group in grouped:
group.plot(ax=ax1, kind='scatter',
x='x', y='y',
label=key, color=mycolorsdict[key])
ax1.legend(loc='upper left', facecolor='white', frameon=1,
framealpha=1, labelspacing=0.2, borderpad=0.25)
I have a time series plot and I would like to add a vertical line to it at event time. If I use this code:
event_time = pd.to_datetime('10/12/2016 06:21:00')
ax = df_stats_t.plot(x = 't', y='t_TI_var_pwr', linestyle='none',...
color = 'black', marker = 'o')
ax1 = ax.twinx()
ax1.axvline(event_time, color='red', linestyle='-')
df_stats_t.plot(x='t',y='t_TI_var_ws',ax=ax1, linestyle='none', ...
color = 'green', marker = 'o')
It takes a subset of the time series starting at event_time and doesn't produce a vertical line.
If I move ax1.axvline(event_time, color='red', linestyle='-') to the bottom, I get the plot I want but the vertical line is still missing.
event_time = pd.to_datetime('10/12/2016 06:21:00')
ax = df_stats_t.plot(x = 't', y='t_TI_var_pwr', linestyle='none',...
color = 'black', marker = 'o')
ax1 = ax.twinx()
df_stats_t.plot(x='t',y='t_TI_var_ws',ax=ax1, linestyle='none',...
color = 'green', marker = 'o')
ax1.axvline(event_time, color='red', linestyle='-')
How can I get the vertical line to discplay at x = event_time for all y values?
works with plt
ax = df_stats_t.plot(x = 't', y='t_TI_var_pwr', linestyle='none', color = 'black', marker = 'o')
ax1 = ax.twinx()
df_stats_t.plot(x='t',y='t_TI_var_ws',ax=ax1, linestyle='none', color = 'green', marker = 'o')
plt.axvline(event_time, color='red', linestyle='-')
I'm trying to reproduce this diagram:
but I'm having trouble creating the horizontal lines with bars. I've tried annotate and hlines but they don't quite give the effect I'm after.
import matplotlib.pyplot as plt
plt.grid(which = 'both')
plt.xticks(fontsize = 16)
plt.yticks(fontsize = 16)
plt.xlim(-0.5,8)
plt.ylim(-0.5,10)
plt.xlabel('Redshift, z', fontsize = 16)
plt.hlines(8, 0, .3)
plt.annotate(r'H$\alpha$', fontsize = 16, xy = (0,8), xycoords='data', xytext=(0,8),
textcoords='data',
arrowprops=dict(arrowstyle='<|-|>', connectionstyle='arc3', color = 'k', lw=2))
fig = plt.gcf()
width, height = 15,35 # inches
fig.set_size_inches(width, height, forward = True)
plt.show()
What's the best way to produce the bars like this?
I would use annotate directly, but for more flexibility, I would separate the drawing of the horizontal bars and the corresponding text
plt.figure()
plt.grid(which = 'both')
plt.xticks(fontsize = 16)
plt.yticks(fontsize = 16)
plt.xlim(-0.5,8)
plt.ylim(-0.5,10)
plt.xlabel('Redshift, z', fontsize = 16)
bar_ys = [8,4]
bar_xs = [[0,6],[3,5]]
bar_texts = [r'H$\alpha$',r'H$\beta$']
bar_color = ['k','orange']
for y,xs,t,c in zip(bar_ys,bar_xs,bar_texts,bar_color):
plt.annotate('', xy = (xs[0],y), xycoords='data', xytext=(xs[1],y),
arrowprops=dict(arrowstyle='|-|', color=c, lw=2, shrinkA=0, shrinkB=0))
plt.annotate(t, xy = (xs[1],y), xycoords='data', xytext=(-5,5), textcoords='offset points',
fontsize = 16, va='baseline', ha='right', color=c)
plt.show()
The accepted answer works perfectly, thank you.
In addition, I automated the colours thus:
colors = iter(cm.tab10(np.linspace(0,0.8,13)))
colour = 'k'
for y,xs,t in zip(bar_ys,bar_xs,bar_texts):
plt.annotate('', xy = (xs[0],y), xycoords='data', xytext=(xs[1],y),
arrowprops=dict(arrowstyle='|-|', color=colour, lw=2, shrinkA=0, shrinkB=0))
plt.annotate(t, xy = (xs[1],y), xycoords='data', xytext=(-5,5), textcoords='offset points',
fontsize = 16, va='baseline', ha='right', color=colour)
colour = next(colors)
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)