I am trying to set the x and y limits on a subplot but am having difficultly. I suspect that the difficultly stems from my fundamental lack of understanding of how figures and subplots work. I have read these two questions:
question 1
question 2
I tried to use that approach, but neither had any effect on the x and y limits. Here's my code:
fig = plt.figure(figsize=(9,6))
ax = plt.subplot(111)
ax.hist(sub_dict['b'], bins=30, color='r', alpha=0.3)
ax.set_ylim=([0,200])
ax.set_xlim=([0,100])
plt.xlabel('x')
plt.ylabel('y')
plt.title('title')
plt.show()
I am confused as whether to apply commands to fig or ax? For instance .xlabel and .title don't seem to be available for ax. Thanks
Why don't you do:
Ax = fig.add_subplot(111)
import matplotlib.pyplot as plt
import numpy as np
mu, sigma = 100, 15
x = mu + sigma*np.random.randn(100)
fig = plt.figure(figsize=(9,6))
ax = fig.add_subplot(111)
ax.hist(x, bins=30, color='r', alpha=0.3)
ax.set_ylim=(0, 200)
ax.set_xlim=(0, 100)
plt.xlabel('x')
plt.ylabel('y')
plt.title('title')
plt.show()
I've run your code on some sample code, and I'm attaching the screenshot. I'm not sure this is the desired result but this is what I got.
For a multiplot, where you have subplots in a single figure, you can have several xlabel and one title
fig.title("foobar")
ax.set_xlabel("x")
This is explained in great detail here on the Matplotlib website.
You in your case, use a subplot for just a single plot. This is possible, just doesn't make a lot of sense. Plots like the one below are supposed to be created with the subplot feature:
To answer your question: you can set the x- and y-limits on a per-subplot and per-axis basis by simply addressing the respective subplot directly (ax for subplot 1) and them calling the set_xlabel member function to set the label on the x-axis.
EDIT
For your updated question:
Use this code as inspiration, I had to generate some data on my own so no guarantees:
import matplotlib.pyplot as plt
plt.hist(sub_dict['b'], bins=30, color='r', alpha=0.3)
plt.ylim(0,200)
plt.xlim(0,100)
plt.xlabel('x')
plt.ylabel('y')
plt.title('title')
plt.show()
Bit more googling and I got the following that has worked:
sub_dict = subset(data_dict, 'b', 'a', greater_than, 10)
fig = plt.figure(figsize=(9,6))
ax = fig.add_subplot(111)
ax.hist(sub_dict['b'], bins=30, color='r', alpha=0.3)
plt.ylim(0,250)
plt.xlim(0,100)
plt.xlabel('x')
plt.ylabel('y')
plt.title('title')
plt.show()
Related
I have a function that inputs a string (the name of the dataframe we're visualizing) and returns two histograms that visualize that data. The first plot (on the left) is the raw data, the one on the right is it after being normalized (same, just plotted using the matplotlib parameter density=True). But as you can see, this leads to transparency issues when the plots overlap. This is my code for this particular plot:
plt.rcParams["figure.figsize"] = [12, 8]
plt.rcParams["figure.autolayout"] = True
ax0_1 = plt.subplot(121)
_,bins,_ = ax0_1.hist(filtered_0,alpha=1,color='b',bins=15,label='All apples')
ax0_1.hist(filtered_1,alpha=0.9,color='gold',bins=bins,label='Less than two apples')
ax0_1.set_title('Condition 0 vs Condition 1: '+'{}'.format(apple_data),fontsize=14)
ax0_1.set_xlabel('{}'.format(apple_data),fontsize=13)
ax0_1.set_ylabel('Frequency',fontsize=13)
ax0_1.grid(axis='y',linewidth=0.4)
ax0_1.tick_params(axis='x',labelsize=13)
ax0_1.tick_params(axis='y',labelsize=13)
ax0_1_norm = plt.subplot(122)
_,bins,_ = ax0_1_norm.hist(filtered_0,alpha=1,color='b',bins=15,label='All apples',density=True)
ax0_1_norm.hist(filtered_1,alpha=0.9,color='gold',bins=bins,label='Less than two apples',density=True)
ax0_1_norm.set_title('Condition 0 vs Condition 1: '+'{} - Normalized'.format(apple_data),fontsize=14)
ax0_1_norm.set_xlabel('{}'.format(apple_data),fontsize=13)
ax0_1_norm.set_ylabel('Frequency',fontsize=13)
ax0_1_norm.legend(bbox_to_anchor=(2, 0.95))
ax0_1_norm.grid(axis='y',linewidth=0.4)
ax0_1_norm.tick_params(axis='x',labelsize=13)
ax0_1_norm.tick_params(axis='y',labelsize=13)
plt.tight_layout(pad=0.5)
plt.show()
What my current plot looks like
Any ideas on how to make the colors blend a bit better would be helpful. Alternatively, if there are any other combinations you know of that would work instead, feel free to share. I'm not picky about the color choice. Thanks!
I think it is better to emphasize such a histogram by distinguishing it by the shape of the histogram or by the difference in transparency rather than visualizing it by color. I have coded an example from the official reference with additional overlap.
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(20211021)
N_points = 100000
n_bins = 20
x = np.random.randn(N_points)
y = .4 * x + np.random.randn(100000) + 2
fig, axs = plt.subplots(2, 2, sharey=True, tight_layout=True)
# We can set the number of bins with the `bins` kwarg
axs[0,0].hist(x, color='b', alpha=0.9, bins=n_bins, ec='b', fc='None')
axs[0,0].hist(y, color='gold', alpha=0.6, bins=21)
axs[0,0].set_title('edgecolor and facecolor None')
axs[0,1].hist(x, color='b', alpha=0.9, bins=n_bins)
axs[0,1].hist(y, color='gold', alpha=0.6, bins=21, ec='b')
axs[0,1].set_title('edgecolor and facecolor')
axs[1,0].hist(x, alpha=0.9, bins=n_bins, histtype='step', facecolor='b')
axs[1,0].hist(y, color='gold', alpha=0.6, bins=21)
axs[1,0].set_title('step')
axs[1,1].hist(x, color='b', alpha=0.9, bins=n_bins, histtype='bar', rwidth=0.8)
axs[1,1].hist(y, color='gold', alpha=0.6, bins=21, ec='b')
axs[1,1].set_title('bar')
plt.show()
I'm learning Python using Jupiter and I'm struggling trying to put the graphs into one figure. Here's what I have so far...
Code for my graphs(I have three of graphs, they only differ in color and lines vs. dot):
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
one = plt.figure()
plt.plot(x_v, y_v, '#008000') #change color using hex strings
plt.xlabel('x')
plt.ylabel('y')
plt.show()
two = plt.figure()
plt.plot(x_v, y_v, linestyle='none', marker='o', markersize=0.5)
plt.show()
three = plt.figure()
plt.plot(x_v, y_v, linestyle='none', marker='o', markersize=0.5, color = 'yellow')
plt.show()
Here's code that I have so far to make it one figure... I was wondering If I should should put it in a np.arange and plot it, but I can't seem to get it to work....
def f(x):
return one
def g(x):
return two
def h(x):
return three
If anyone can help, it'll be of great use! Thank you!
You can use plt.subplots:
fig, (ax1, ax2, ax3) = plt.subplots(figsize=(15, 5), ncols=3)
ax1.plot(x_v, y_v, '#008000')
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax2.plot(x_v, y_v, linestyle='none', marker='o', markersize=0.5)
ax3.plot(x_v, y_v, linestyle='none', marker='o', markersize=0.5, color = 'yellow')
Here is one way to approach multiple plots with plt.subplots. I think it is very easy to follow and also gives a lot of control over individual plots:
import numpy as np
import matplotlib.pyplot as plt
#generating test data
x = np.arange(0,9)
y = np.arange(1,10)
#defining figure layout (i.e. rows, columns, size, horizontal and vertical space between subplots
fig,ax = plt.subplots(nrows=2,ncols=2,figsize=(15,7))
plt.subplots_adjust(hspace=0.4,wspace=0.2)
#first subplot (numbering can be read as 1st plot in a grid of 2x2)
plt.subplot(2,2,1)
plt.plot(x,y)
#second subplot in a grid of 2x2
plt.subplot(2,2,2)
plt.plot(x,y,ls='--')
#third subplot in a grid of 2x2
plt.subplot(2,2,3)
plt.scatter(x,y)
#fourth subplot in a grid of 2x2
plt.subplot(2,2,4)
plt.plot(x,y)
plt.tight_layout()
plt.show()
Output:
In pyplot, you can change the order of different graphs using the zorder option or by changing the order of the plot() commands. However, when you add an alternative axis via ax2 = twinx(), the new axis will always overlay the old axis (as described in the documentation).
Is it possible to change the order of the axis to move the alternative (twinned) y-axis to background?
In the example below, I would like to display the blue line on top of the histogram:
import numpy as np
import matplotlib.pyplot as plt
import random
# Data
x = np.arange(-3.0, 3.01, 0.1)
y = np.power(x,2)
y2 = 1/np.sqrt(2*np.pi) * np.exp(-y/2)
data = [random.gauss(0.0, 1.0) for i in range(1000)]
# Plot figure
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
ax2.hist(data, bins=40, normed=True, color='g',zorder=0)
ax2.plot(x, y2, color='r', linewidth=2, zorder=2)
ax1.plot(x, y, color='b', linewidth=2, zorder=5)
ax1.set_ylabel("Parabola")
ax2.set_ylabel("Normal distribution")
ax1.yaxis.label.set_color('b')
ax2.yaxis.label.set_color('r')
plt.show()
Edit: For some reason, I am unable to upload the image generated by this code. I will try again later.
You can set the zorder of an axes, ax.set_zorder(). One would then need to remove the background of that axes, such that the axes below is still visible.
ax2 = ax1.twinx()
ax1.set_zorder(10)
ax1.patch.set_visible(False)
In pyplot, you can change the order of different graphs using the zorder option or by changing the order of the plot() commands. However, when you add an alternative axis via ax2 = twinx(), the new axis will always overlay the old axis (as described in the documentation).
Is it possible to change the order of the axis to move the alternative (twinned) y-axis to background?
In the example below, I would like to display the blue line on top of the histogram:
import numpy as np
import matplotlib.pyplot as plt
import random
# Data
x = np.arange(-3.0, 3.01, 0.1)
y = np.power(x,2)
y2 = 1/np.sqrt(2*np.pi) * np.exp(-y/2)
data = [random.gauss(0.0, 1.0) for i in range(1000)]
# Plot figure
fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
ax2.hist(data, bins=40, normed=True, color='g',zorder=0)
ax2.plot(x, y2, color='r', linewidth=2, zorder=2)
ax1.plot(x, y, color='b', linewidth=2, zorder=5)
ax1.set_ylabel("Parabola")
ax2.set_ylabel("Normal distribution")
ax1.yaxis.label.set_color('b')
ax2.yaxis.label.set_color('r')
plt.show()
Edit: For some reason, I am unable to upload the image generated by this code. I will try again later.
You can set the zorder of an axes, ax.set_zorder(). One would then need to remove the background of that axes, such that the axes below is still visible.
ax2 = ax1.twinx()
ax1.set_zorder(10)
ax1.patch.set_visible(False)
I am working on matplotlib and created some graphs like bar chart, bubble chart and others.
Can some one please explain with an example what is difference between line graph and sparkline graph and how to draw spark line graphs in python using matplotlib ?
for example with the following code
import matplotlib.pyplot as plt
import numpy as np
x=[1,2,3,4,5]
y=[5,7,2,6,2]
plt.plot(x, y)
plt.show()
the line graph generated is the following:
But I couldn't get what is the difference between a line chart and a spark lien chart for the same data. Please help me understand
A sparkline is the same as a line plot but without axes or coordinates. They can be used to show the "shape" of the data in a compact way.
You can cram several line plots in the same figure just by using subplots and changing properties of the resulting Axes for each subplot:
data = np.cumsum(np.random.rand(1000)-0.5)
data = data - np.mean(data)
fig = plt.figure()
ax1 = fig.add_subplot(411) # nrows, ncols, plot_number, top sparkline
ax1.plot(data, 'b-')
ax1.axhline(c='grey', alpha=0.5)
ax2 = fig.add_subplot(412, sharex=ax1)
ax2.plot(data, 'g-')
ax2.axhline(c='grey', alpha=0.5)
ax3 = fig.add_subplot(413, sharex=ax1)
ax3.plot(data, 'y-')
ax3.axhline(c='grey', alpha=0.5)
ax4 = fig.add_subplot(414, sharex=ax1) # bottom sparkline
ax4.plot(data, 'r-')
ax4.axhline(c='grey', alpha=0.5)
for axes in [ax1, ax2, ax3, ax4]: # remove all borders
plt.setp(axes.get_xticklabels(), visible=False)
plt.setp(axes.get_yticklabels(), visible=False)
plt.setp(axes.get_xticklines(), visible=False)
plt.setp(axes.get_yticklines(), visible=False)
plt.setp(axes.spines.values(), visible=False)
# bottom sparkline
plt.setp(ax4.get_xticklabels(), visible=True)
plt.setp(ax4.get_xticklines(), visible=True)
ax4.xaxis.tick_bottom() # but onlyt the lower x ticks not x ticks at the top
plt.tight_layout()
plt.show()
A sparkline graph is just a regular plot with all the axis removed. quite simple to do with matplotlib:
import matplotlib.pyplot as plt
import numpy as np
# create some random data
x = np.cumsum(np.random.rand(1000)-0.5)
# plot it
fig, ax = plt.subplots(1,1,figsize=(10,3))
plt.plot(x, color='k')
plt.plot(len(x)-1, x[-1], color='r', marker='o')
# remove all the axes
for k,v in ax.spines.items():
v.set_visible(False)
ax.set_xticks([])
ax.set_yticks([])
#show it
plt.show()