I am plotting a bar graph using matplotlib and according to a condition in my code I need to change the color of one of the bar. Is it possible to change the color of a single bar in the plot without plotting a new bar graph, because that would increase the complexity ?
Related: how to change the color of a single bar if condition is True matplotlib
matplotlib.pyplot.bar returns a matplotlib.container.BarContainer, in which the individual bars are stored as matplotlib.patches.Rectangle objects. Given that
The container can be treated as a tuple of the patches themselves. Additionally, you can access these and further parameters by the attributes
You can extract the patch for the specific bar or bars you want and change its color. An example:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 5)
bars = plt.bar(x, x)
bars[2].set_color('orange')
plt.show()
Related
graph
how do I make this graph infill all the square around it? (I colored the part that I want to take off in yellow, for reference)
Normally I use two methods to adjust axis limits depending on a situation.
When a graph is simple, axis.set_ylim(bottom, top) method is a quick way to directly change y-axis (you might know this already).
Another way is to use matplotlib.ticker. It gives you more utilities to adjust axis ticks in your graph.
https://matplotlib.org/3.1.1/gallery/ticks_and_spines/tick-formatters.html
I'm guessing you're using a list of strings to set yaxis tick labels. You may want to set locations (float numbers) and labels (string) of y-axis ticks separatedly. Then set the limits on locations like the following snippet.
import matplotlib.pyplot as plt
import matplotlib.ticker as mt
fig, ax = plt.subplots(1,1)
ax.plot([0,1,2], [0,1,2])
ax.yaxis.set_major_locator(mt.FixedLocator([0,1,2]))
ax.yaxis.set_major_formatter(mt.FixedFormatter(["String1", "String2", "String3"]))
ax.set_ylim(bottom=0, top=2)
It gives you this: generated figure
Try setting the min and max of your x and y axes.
I need four different color bars for a single plot. My plot consists of 5 subplots, but only the first one requires four different color bar plots. I would like to position them below a graph. I achieved it, but my color bars are of different sizes:
For your reference, my figure is split into 5 figures using the matplotlib subplot2grid method. A minimal working example (without subplot2grid) is shown below:
import matplotlib.pyplot as plt
import numpy as np
frame = np.zeros([512, 512])
fig = plt.figure(figsize=(16, 8))
ax = plt.imshow(frame)
for i in range(4):
plt.colorbar(fraction=0.046, pad=0.04, location="bottom")
plt.show()
How do I position the color bar plots below the plot and them next to each other and of the same length (e.g. the same length as the first bar plot, or image size)?
It's easier to ask this with a figure. At the moment i obtain the following boxplot graph using matplotlib:
Is there a way to obtain a figure like that, but with each box in a position coherent with the corresponding x-axis number (like in a normal scatter plot, but with boxes instead of points)?
At the moment the numbers on the x-axis are added by means of the labels= argument.
You need to specify the positions argument to the boxplot constructor.
from matplotlib import pyplot as plt
plt.boxplot([[1,4],[2,5],[3,6]], positions=[2,4,5.5])
By default it uses the values [1, 2, ..., n] but you can specify a different x position for each bar and the xticks will be updated automatically.
I'm trying to add a color bar in a graph, but I don't understand how it works. The problem is that I make my own colorcode by:
x = np.arange(11)
ys = [i+x+(i*x)**2 for i in range(11)]
colors = cm.rainbow(np.linspace(0, 1, len(ys)))
and colors[i] will give me a new color. Then I use (homemade) functions to select the relevant data and plot them accordingly. This would look something like this:
function(x,y,concentration,temperature,1,37,colors[0])
function(x,y,concentration,temperature,2,37,colors[1])
# etc
Now I want to add the colors in a color bar, with labels I can change. How do I do this?
I have seen several examples where you plot all the data as one array, with automated color bars, but here I plot the data one by one (by using functions to select the relevant data).
EDIT:
function(x,y,concentration,temperature,1,37,colors[0]) looks like this (simplified):
def function(x,y,c,T,condition1,condition2,colors):
import matplotlib.pyplot as plt
i=0
for element in c:
if element == condition1:
if T[i]==condition2:
plt.plot(x,y,color=colors,linewidth=2)
i=i+1
return
Drawing a colorbar aside a line plot
Please map my solution (I used simply 11 sines of different amplitudes) to your problem (as I told you, it is difficult to understand from what you wrote in your Q).
import matplotlib
import numpy as np
from matplotlib import pyplot as plt
# an array of parameters, each of our curves depend on a specific
# value of parameters
parameters = np.linspace(0,10,11)
# norm is a class which, when called, can normalize data into the
# [0.0, 1.0] interval.
norm = matplotlib.colors.Normalize(
vmin=np.min(parameters),
vmax=np.max(parameters))
# choose a colormap
c_m = matplotlib.cm.cool
# create a ScalarMappable and initialize a data structure
s_m = matplotlib.cm.ScalarMappable(cmap=c_m, norm=norm)
s_m.set_array([])
# plotting 11 sines of varying amplitudes, the colors are chosen
# calling the ScalarMappable that was initialised with c_m and norm
x = np.linspace(0,np.pi,31)
for parameter in parameters:
plt.plot(x,
parameter*np.sin(x),
color=s_m.to_rgba(parameter))
# having plotted the 11 curves we plot the colorbar, using again our
# ScalarMappable
plt.colorbar(s_m)
# That's all, folks
plt.show()
Example
Acknowledgements
A similar problem, about a scatter plot
Update — April 14, 2021
With recent versions of Matplotlib, the statement s_m.set_array([]) is not required any more. On the other hand, it does no harm.
When plotting, in place of color=s_m.to_rgba(parameter) one may want to use the (slightly) more obvious color=c_m(norm(parameter)).
I am plotting things using matplotlib and Basemap (within a wxpython gui). Currently, my plot code look something like this:
self.map = Basemap(llcrnrlon=lon_L, llcrnrlat=lat_D, urcrnrlon=lon_R,
urcrnrlat=lat_U, projection='lcc', lat_0=map_lat1, lon_0=map_lon1,
resolution='i', area_thresh=10000,ax=self.axes, fix_aspect=False)
m = Basemap(llcrnrlon=lon_L, llcrnrlat=lat_D, urcrnrlon=lon_R,
urcrnrlat=lat_U, projection='lcc', lat_0=map_lat1, lon_0=map_lon1,
resolution='i', area_thresh=10000,ax=self.axes)
x,y=m(some_x_data,some_y_data)
plot_handle, = self.map.plot(x,y,'bo')
plot_handle.set_xdata(x)
plot_handle.set_ydata(y)
self.figure.canvas.draw()
This plots it just fine. Now what I want to do is take a single point (single x and single y within my data) and color it a different color. I still want to use the plot_handle because I am constantly updating the map/plot -- so i don't want to just reset my data. Any help?
Thanks!
If you use scatter (doc) you can set and update the color of each point.
import matplotlib.pylab as plt
x,y = m(some_x,some_y)
c = iterator_of_colors
plt_handle, = self.map.scatter(x,y,c=c)
# some code
c[j] = new_color # update you color list
plt_handle.set_array(c) # update the colors in the graph
plt.draw()
It looks a little strange to use set_array but that is how matplotlib deals with scatter plots internally (it looks like they use the same class that is used for displaying images, only just color in markers instead of squares in the grid).
Do a new plot_handle for the specific plot with a different marker:
plot_handle1, = self.map.plot([x[i]], [y[i]], 'ro')
You'll then have to update this every time you want to change that point's position. It's not possible to use only one plot_handle and have points showing with different markers.