Black bar covering my x labels for matplotlib plot? - python

I am trying to play a figure and I am having a black box pop up on the bottom of the plot where the x labels should be. I tried this command from a similar question on here in the past:
from matplotlib import rcParams
rcParams.update({'figure.autolayout': True})
But the problem was still the same. Here is my current code:
import pylab
from matplotlib import rcParams
rcParams.update({'figure.autolayout': True})
df['date'] = df['date'].astype('str')
pos = np.arange(len(df['date']))
plt.bar(pos,df['value'])
ticks = plt.xticks(pos, df['value'])
And my plot is attached here. Any help would be great!

pos = np.arange(len(df['date'])) and ticks = plt.xticks(pos, df['value']) are causing the problem you are having. You are putting an xtick at every value you have in the data frame.
Don't know how you data looks like and what's the most sensible way to do this. ticks = plt.xticks(pos[::20], df['value'].values[::20], rotation=90) will put a tick every 20 rows that would make the plot more readable.

It actually is not a black bar, but rather all of your x-axis labels being crammed into too small of a space. You can try rotating the axis labels to create more space or just remove them all together.

Related

Seaborn clustermap legend overlap with figure

'''
Hi there,
I created a clustermap using seaborn. Because the legend overlaps with the figure, I'd like to move it. However, plt.legend(bbox_to_anchor=(1,1)) gave the following error 'No handles with labels found to put in legend.'
That makes me wonder: what is the color scale -20 to 20 on the top left that I want to re-position? isn't that a legend?
Thank you in advance for shedding light on that for me.
'''
import matplotlib.pyplot as plt
import seaborn as sns
g = sns.clustermap(data=df_highestPivot,cmap='coolwarm')
plt.legend(bbox_to_anchor=(1,1)) #This line generate the error
plt.savefig('plot.png',dpi=300,bbox_to_inches='tight')
plt.show()
plt.close()
The colorbar is not a legend per se (not an object of type Legend at least). It is actually it's own subplots Axes, that you can access using g.ax_cbar.
If you want to move it, you can pass an argument cbar_pos= to clustermap(). However, it's complicated to find an empty space in the figure to place it. I would recommend you make some room using subplots_adjust() then move the ax_cbar Axes at the desired location
iris = sns.load_dataset('iris')
species = iris.pop("species")
g = sns.clustermap(iris)
g.fig.subplots_adjust(right=0.7)
g.ax_cbar.set_position((0.8, .2, .03, .4))

Matplotlib bar graphs: increase spacing between bars

I'm new to matplotlib and it seems like there's no direct method for increasing the space between bars in a bar graph rendering of data. There are posts on this but the responses say that one has to play with the width of bars or the scale of the x axis which is not what I'm looking for because that will just make my bar skinnier or lead to overlapping and scaling the x axis wouldn't work for non-numerical tick values (right?). I would specifically like to increase the space between the bars which makes sense for the data below:
import matplotlib.pyplot as plt
plt.bar('state','n_incidents',data=top_5_gun_violence_states)
plt.xlabel('States')
plt.ylabel('# of incidents')
plt.title('Statewise gun violence graph')
plt.xticks(rotation=90)
# plt.figure(figsize=(20, 3))
plt.show()
The output looks like this:
matplotlib bar plot
Clearly, this needs more spacing between bars as state names are squeezed together. Any help would be appreciated! Thanks!

Matplotlib: Change color of individual grid lines

I've only been using Python for about a month now, so I'm sorry if there's some simple solution to this that I overlooked.
Basically I have a figure with 4 subplots, the 2 on the left show longitudinal plots and the ones on the right show scatter plots at certain points of the longitudinal plots. You can click through the scatter plots at different points of the longitudinal plot with buttons, and the tick label of the longitudinal plot you're currently at will be highlighted in blue.
Coloring a certain tick label already works with this:
xlabels = []
labelcolors = []
for i, item in enumerate(mr.segmentlst):
if re.search('SFX|MC|MQ|MS|MKC', item):
xlabels.append(mr.segmentlst[i])
else:
xlabels.append('')
for i, item in enumerate(mr.segmentlst):
if re.search('SFX', item):
labelcolors.append('black')
else:
labelcolors.append('gray')
labelcolors[self.ind]='blue'
[t.set_color(i) for (i,t) in zip(labelcolors, ax1.xaxis.get_ticklabels())]
[t.set_color(i) for (i,t) in zip(labelcolors, ax2.xaxis.get_ticklabels())]
It only shows certain tick labels and changes their colors accordingly (I don't know if there is another solution for this, it's the only one I could find). Don't mind the mr.segmentlist, I've currently hardcoded the plot to use an attribute from another method so I can easily keep testing it in Spyder.
I'd like to also change the grid line color of the currently highlighted tick label (only xgridlines are visible) in the longitudinal plots, is there some kind of similar way of doing this? I've searched the internet for a solution for about 2 hours now and didn't really find anything helpful.
I thought something like ax1.get_xgridlines() might be used, but I have no idea how I could transform it into a useful list.
Thanks,
Tamara
get_xgridlines() returns a list of Line2D objects, so if you can locate which line you want to modify, you can modify any of their properties
x = np.random.random_sample((10,))
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(x,x)
ax.grid()
a = ax.get_xgridlines()
b = a[2]
b.set_color('red')
b.set_linewidth(3)
since the above solution only works with major gridlines
(since get_gridlines() is currently hardcoded to use only the major ones),
here's how you can also access the minor gridlines by adapting
the get_gridlines() function (from here):
from matplotlib import cbook
def get_gridlines(ax, which):
'''
Parameters:
ax : ax.xaxis or ax.yaxis instance
which : 'major' or 'minor'
Returns:
The grid lines as a list of Line2D instance
'''
if which == 'major':
ticks = ax.get_major_ticks()
if which == 'minor':
ticks = ax.get_minor_ticks()
return cbook.silent_list('Line2D gridline',
[tick.gridline for tick in ticks])

remove tick labels in Python but keep gridlines

I have a Python script which is producing a plot consisting of 3 subplots all in 1 column.
In the middle subplot, I currently have gridlines, but I want to remove the x axis tick labels.
I have tried
ax2.axes.get_xaxis().set_ticks([])
but this seems to remove the gridlines also.
How can I remove the tick labels and keep the gridlines please?
Please try this:
plt.grid(True)
ax2.axes.get_xaxes().set_ticks([])
Or maybe this:
from matplotlib.ticker import NullFormatter
ax2.axes.get_xaxis().set_major_formatter(NullFormatter())

how to adjust # of ticks on Bokeh axis (labels are overlapping on small figures)

I have a multi-figure Bokeh plot of vertically stacked & aligned figures. Because I want to align the plots vertically, the y-axis labels are rotated to be vertical rather than horizontal.
In certain scenarios, Bokeh produces too many ticks, such that the tick labels overlap completely, making illegible. Here is an example:
import bokeh.plotting as bp
import numpy as np
y = np.random.uniform(0, 300, 50)
x = np.arange(len(y))
bp.output_file("/tmp/test.html", "test")
plot = bp.figure(plot_width=800, plot_height=200)
plot.yaxis.axis_label_text_font_size = "12pt"
plot.yaxis.major_label_orientation = 'vertical'
plot.line (x,y)
bp.show(plot)
Short of making the renderer clever enough to produce fewer labels automatically, is there a way to indicate the # of labels to be placed on an axis?
It seems that the # of labels generated has to do with the range of the data, in terms of its affinity to a power of 10.
You can control the number of ticks now with desired_num_ticks property. Look at the example from the bokeh docs (and this issue).
For example, in your case, something like this: plot.yaxis[0].ticker.desired_num_ticks = 10.
Looks like there is still no direct way to specify this. Please follow the related issue. This is a workaround:
from bokeh.models import SingleIntervalTicker, LinearAxis
plot = bp.figure(plot_width=800, plot_height=200, x_axis_type=None)
ticker = SingleIntervalTicker(interval=5, num_minor_ticks=10)
xaxis = LinearAxis(ticker=ticker)
plot.add_layout(xaxis, 'below')
You can control the number of tickets via the interval parameter in SingleIntervalTicker.

Categories