Background color of Matplotlib - matplotlib

# use a gray background
ax = plt.axes(facecolor='#E6E6E6')
ax.set_axisbelow(True)
# draw solid white grid lines
plt.grid(color='w', linestyle='solid')
# hide axis spines
for spine in ax.spines.values():
spine.set_visible(True)
# hide top and right ticks
ax.xaxis.tick_bottom()
ax.yaxis.tick_left()
# lighten ticks and labels
ax.tick_params(colors='gray', direction='out')
for tick in ax.get_xticklabels():
tick.set_color('gray')
for tick in ax.get_yticklabels():
tick.set_color('gray')
# control face and edge color of histogram
ax.hist(x, edgecolor='#E6E6E6', color='#EE6666');
Output:
The codes above generate the pic attached. How can I get rid of the black frame circulating the axes?

The "black frame" surrounding your image is part of the figure container. The short answer is, change the facecolor of the figure. (i.e. add, fig = plt.figure(facecolor='white') above your first line.)
# THIS LINE CONTROLS THE FIGURE FACECOLOR. YOU CAN USE HEX COLOR RGB OR JUST SPECIFY A COLOR
fig = plt.figure(facecolor='white')
# use a gray background
ax = plt.axes(facecolor='#E6E6E6')
ax.set_axisbelow(True)
# draw solid white grid lines
plt.grid(color='w', linestyle='solid')
# hide axis spines
for spine in ax.spines.values():
spine.set_visible(True)
# hide top and right ticks
ax.xaxis.tick_bottom()
ax.yaxis.tick_left()
# lighten ticks and labels
ax.tick_params(colors='gray', direction='out')
for tick in ax.get_xticklabels():
tick.set_color('gray')
for tick in ax.get_yticklabels():
tick.set_color('gray')
# control face and edge color of histogram
ax.hist(x, edgecolor='#E6E6E6', color='#EE6666');

Related

No Plotting all values of X in xaxis and why there is the background grey?

I would like to get a plot with less data on xaxis. I have this very simple script. I put a 'range' for xaxis. Furthemore I would like that my background was white with contours black and not grey (see figure). How can I do?
import matplotlib.pyplot as plt
plt.figure()
# Increase the plot size and font size.
plt.rcParams["figure.figsize"] = (60,30)
plt.xticks(fontsize=40)
plt.yticks(fontsize=40)
plt.grid(True, color='gray', linestyle='dashed', linewidth=0.5, axis='y')
# Plot the learning curve.
plt.plot(df_stats['Training Loss'], color='b', marker='.', linestyle='solid', mec='b', markersize=24, markerfacecolor='white', label="Training", linewidth=7)
plt.plot(df_stats['Valid. Loss'], color='g', marker='.', linestyle='solid', mec='b', markersize=24, markerfacecolor='white',label="Validation", linewidth=7)
# Label the plot.
plt.title("Training & Validation Loss",fontsize=60)
plt.xlabel("Epoch", fontsize=52)
plt.ylabel("Loss", fontsize=52)
plt.legend(fontsize=50)
plt.xticks(list(range(1, 72)))
plt.show()
To set the X-axis ticks to a lower frequency, you will need to change the xticks to a lower frequency. One way to do this using numpy.arange().
Regarding the background color, the default is white. But, if for reason it is not, you can set it to white using the plot and axis facecolor() to white explicitly.
The code below is the updated version with these changes. Note that I used some dummy data to demonstrate the same.
Code
df_stats= pd.DataFrame(columns=['Training Loss', 'Valid. Loss'])
df_stats['Training Loss'] = list(range(1,72))
df_stats['Valid. Loss'] = df_stats['Training Loss'] * 2.1
import matplotlib.pyplot as plt
plt.figure()
# Background color of outer area
plt.figure(facecolor='white')
# Background color of the plot area
ax = plt.axes()
ax.set_facecolor("white")
# Increase the plot size and font size.
plt.rcParams["figure.figsize"] = (60,30)
plt.xticks(fontsize=40)
plt.yticks(fontsize=40)
plt.grid(True, color='gray', linestyle='dashed', linewidth=0.5, axis='y')
# Plot the learning curve.
plt.plot(df_stats['Training Loss'], color='b', marker='.', linestyle='solid', mec='b', markersize=24, markerfacecolor='white', label="Training", linewidth=7)
plt.plot(df_stats['Valid. Loss'], color='g', marker='.', linestyle='solid', mec='b', markersize=24, markerfacecolor='white',label="Validation", linewidth=7)
# Label the plot.
plt.title("Training & Validation Loss",fontsize=60)
plt.xlabel("Epoch", fontsize=52)
plt.ylabel("Loss", fontsize=52)
plt.legend(fontsize=50)
plt.xticks(list(np.arange(1, 72, 9)))
plt.show()
Output plot

matplotlib: Draw ontop of image - keep colorbar range

I want to draw into the same figure while keeping the colorbar and it's range. How to do that?
Sounds easy, but apparantly it's not:
cbar = plt.colorbar()
cbar.set_clim(vmin=-1.0, vmax=1.0)
plt.show(block=False)
for i in range(num_maps):
plt.imshow(img) # img to draw the data ontop of
data = all_data[:,:,i]
plt.imshow(data, alpha=0.5) # data to draw
plt.pause(0.5)
I assume because I first plot the image my colobar range gets destroyed as it has values between [0..255]. Any idea how to suppress that behaviour?
Looks like I have to call colobar() after setting the range...
plt.set_clim(vmin=-1.0, vmax=1.0) # <--- swaped
plt.colorbar() # <--- swaped
plt.show(block=False)
for i in range(num_maps):
plt.imshow(img) # img to draw the data ontop of
data = all_data[:,:,i]
# imshow resets the colorbar -> again specify vmin and vmax
plt.imshow(data, alpha=0.5, vmin=-1.0, vmax=1.0)
plt.pause(0.5)
now it works...

How do I add colour code to Matplotlib legend

I'm trying to add a legend to a matplotlib radar/polar graph. I am very new to matplotlib so please excuse the code. I also expect this is very simple but I've been at it an hour and got nowhere.
I have the following which produces a list of labels in the bottom left corner but whenever I try to add handles to give the color representing the label I lose the legend.
# Set color of axes
plt.rc('axes', linewidth=0.5, edgecolor="#888888")
# Create polar plot
ax = plt.subplot(111, polar=True)
# Set clockwise rotation. That is:
ax.set_theta_offset(pi / 2)
ax.set_theta_direction(-1)
# Set position of y-labels
ax.set_rlabel_position(0)
# Set color and linestyle of grid
ax.xaxis.grid(True, color="#888888", linestyle='solid', linewidth=0.5)
ax.yaxis.grid(True, color="#888888", linestyle='solid', linewidth=0.5)
# Plot data
ax.plot(x_as, values, linewidth=0, linestyle='solid', zorder=3)
# Fill area
ax.fill(x_as, values, 'r', alpha=0.3)
plt.legend(labels=[self.get_object().name], loc=(-.42,-.13))
if not self.get_object().subscription is None:
if self.get_object().subscription.benchmark:
bx = plt.subplot(111, polar=True)
bx.plot(x_as, baseline, linewidth=0, linestyle='solid', zorder=3)
bx.fill(x_as, baseline, 'b', alpha=0.3)
plt.legend(labels=[self.get_object().name, 'Benchmark'], loc=(-.42,-.13))
I believe I need
plt.lengend(handles=[some list], labels=[self.get_object().name, 'Benchmark'], loc=(-.42,-.13))
I do not understand what the list of handles should be and I've tried a number of things, including [ax, bx], [ax.plt(), bx.plt()], ['r', 'b']
From the documentation:
handles : sequence of Artist, optional
A list of Artists (lines, patches) to be added to the legend. Use this together with labels, if you need full control on what is shown
in the legend and the automatic mechanism described above is not
sufficient.
The length of handles and labels should be the same in this case. If they are not, they are truncated to the smaller length.
plt.plot returns a list a line2D objects which is what you need to pass to plt.legend(). Therefore a simplified example is as follows:
labels = ["Line 1", "Line 2"]
lines1, = plt.plot([1,2,3])
lines2, = plt.plot([3,2,1])
handles = [lines1, lines2]
plt.legend(handles, labels)
plt.show()

multiple markers in legend

My script for plotting creates two legends for each label. I do not know how to make legend() not duplicate. I checked on stackoverflow and found two methods. But I could not implement them here. Any ideas?
Matplotlib: Don't show errorbars in legend
Stop matplotlib repeating labels in legend
symbols = [u'\u2193']
#Plotting our vsini values
for i, symbol in enumerate(symbols):
for x0,y0 in zip(vsini_slit_cl, vsini_slit):
plt.text(x0,y0, symbol, fontname='STIXGeneral', size = 10, va='center', ha='center', clip_on=True,color = '#737373')
for i, symbol in enumerate(symbols):
for x0, y0 in zip(vsini_cl_sl, vsini_sl):
plt.text(x0, y0, symbol, fontname='STIXGeneral', size = 10, va='center', ha='center', clip_on=True)
# PLOTTING VSINI FROM LITERATURE
plt.plot((vmag_lit-jmag_lit), vsini_lit, 'o', color = '#a6a6a6', label='Literature')
# PLOTTING SLOW VSINI FROM LITERATURE
plt.plot(vsini_slit_cl, vsini_slit, 'o', color = '#a6a6a6')
# PLOTTING VSINI FROM OUR WORK
plt.plot(vsini_cl_sl, vsini_sl, 'o', label='This Work' )
plt.errorbar(vsini_color, vsini_chad, yerr=vsini_chad_sig, fmt='bo', capsize=3)
plt.legend()
plt.savefig('vsini_colors.jpg', dpi=200)
Just use
plt.legend(numpoints=1)
The default behavior is to use 2 points, which is what you need to make a legend entry for lines.
See: legend user guide and plt.legend doc and legend doc

small scatter plot markers in matplotlib are always black

I'm trying to use matplotlib to make a scatter plot with very small gray points. Because of the point density, the points need to be small. The problem is that the scatter() function's markers seem to have both a line and a fill. When the markers are small, only the line is visible, not the fill, and the line isn't the right colour (it's always black).
I can get exactly what I want using gnuplot: plot 'nodes' with points pt 0 lc rgb 'gray'
How can I make very small gray points using matplotlib scatterplot()?
scatter([1,2,3], [2,4,5], s=1, facecolor='0.5', lw = 0)
This sets the markersize to 1 (s=1), the facecolor to gray (facecolor='0.5'), and the linewidth to 0 (lw=0).
If the marker has no face (cannot be filled, e.g. '+','x'), then the edgecolor has to be set instead of c, and lw should not be 0:
scatter([1,2,3], [2,4,5], marker='+', edgecolor='r')
The following will no work
scatter([1,2,3], [2,4,5], s=1, marker='+', facecolor='0.5', lw = 0)
because the edge/line will not be displayed, so nothing will be displayed.
The absolute simplest answer to your question is: use the color parameter instead of the c parameter to set the color of the whole marker.
It's easy to see the difference when you compare the results:
from matplotlib import pyplot as plt
plt.scatter([1,2,3], [3,1,2], c='0.8') # marker not all gray
plt.scatter([1,2,3], [3,1,2], color='0.8') # marker all gray
Details:
For your simple use case where you just want to make your whole marker be the same shade of gray color, you really shouldn't have to worry about things like face color vs edge color, and whether your marker is defined as all edges or some edges and some fill. Instead, just use the color parameter and know that your whole marker will be set to the single color that you specify!
In response to zwol's question in comment - my reputation is not high enough to leave comments, so this will have to do: In the event that your colors come from a colormap (i.e., are from a "sequence of values to be mapped") you can use color = as demonstrated in the following:
from matplotlib import pyplot
x = [1,5,8,9,5]
y = [4,2,4,7,9]
numSides = [2,3,1,1,5]
cmap = pyplot.cm.get_cmap("copper_r")
min, max = min(numSides), max(numSides)
for i in range(len(x)):
if numSides[i] >= 2:
cax = pyplot.scatter(x[i], y[i], marker = '+', s = 100, c = numSides[i], cmap = cmap)
cax.set_clim(min, max)
elif numSides[i] == 1:
pyplot.scatter(x[i], y[i], marker = '.', s = 40, color = cmap(numSides[i]))
fig = pyplot.gcf()
fig.set_size_inches(8.4, 6)
fig.savefig('figure_test.png', dpi = 200)
pyplot.show()