Related
I am writing code for my internship and I am trying to modify the font size on my axes so that it can look a bit better. The section that does not seem to be working is this part.
ax.set_xticks([-95, -97, -99, -101, -103])
ax.set_yticks([33, 34, 35, 36, 37])
secax = ax.secondary_yaxis(1.0)
secax.set_yticks([33, 34, 35, 36, 37])
ax.tick_params(axis = 'both', labelsize = 16)
When I run all of my code x axis and first y axis font size changes fine but my secondary y axis font size does not change. Is there any way I can change the font size of my secondary y axis?
This is the output I get when I run the code:
In your code, ax.tick_params(axis = 'both', labelsize = 16) changes font size for primary axes. To set fonts for secondary axis add the line secax.tick_params(labelsize=16).
Here's a working MRE
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
xdata = list(range(10))
yF = 85 + 10*np.random.random((10,1))
def fahrenheit_to_celsius(x):
return (x - 32) / 1.8
def celsius_to_fahrenheit(x):
return x * 1.8 + 32
yC = (yF-32)/1.8
ax.plot(xdata, yF)
secax = ax.secondary_yaxis('right', functions = (fahrenheit_to_celsius, celsius_to_fahrenheit))
ax.tick_params(axis = 'both', labelsize = 16)
secax.tick_params(labelsize = 16)
plt.show()
Another strategy is to add a block of code near the top of your file to control font sizes. I don't remember where I found this code, but it comes in handy. Interestingly setting xtick or ytick labelsize also works for secondary axes:
SMALL_SIZE = 10
MEDIUM_SIZE = 16
BIGGER_SIZE = 18
plt.rc('font', size=SMALL_SIZE) # controls default text sizes
plt.rc('axes', titlesize=MEDIUM_SIZE) # fontsize of the axes title
plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels
plt.rc('xtick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels
plt.rc('ytick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels
plt.rc('legend', fontsize=SMALL_SIZE) # legend fontsize
plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title
plt.rc('axes', titleweight='bold') # fontsize of the axes title
plt.rc('axes', labelweight='bold') # fontsize of the x and y labels
I would like to delete the lines which are actually shown in the picture and also put the number (their values) in each graph, I mean the value which belong to each one. How can I do it?
The values are from a data set taken from Kaggle.
Here is some code to help you get the requested layout.
The states and the numbers are from Wikipedia.
import matplotlib.pyplot as plt
states = ['Acre', 'Alagoas', 'Amazonas', 'Amapá', 'Bahia', 'Ceará', 'Federal District',
'Espírito Santo', 'Goiás', 'Maranhão', 'Minas Gerais', 'Mato Grosso do Sul',
'Mato Grosso', 'Pará', 'Paraíba', 'Pernambuco', 'Piauí', 'Paraná', 'Rio de Janeiro',
'Rio Grande do Norte', 'Rondônia', 'Roraima', 'Rio Grande do Sul', 'Santa Catarina',
'Sergipe', 'São Paulo', 'Tocantins']
fires = [2918, 73, 7625, 24, 2383, 327, 68, 229, 1786, 5596, 2919, 451, 15476, 10747, 81, 132,
2818, 181, 396, 68, 6441, 4608, 2029, 1107, 62, 1616, 6436]
fires, states = zip(*sorted(zip(fires, states))) #sort both arrays on number of fires
fires = fires[-15:] # limit to the 15 highest numbers
states = states[-15:]
fig, ax = plt.subplots(figsize=(8, 6))
ax.barh(states, fires, color="#08519c")
plt.box(False) # remove the complete box around the plot
plt.xticks([]) # remove all the ticks on the x-axis
ax.yaxis.set_ticks_position('none') # removes the tick marks on the y-axis but leaves the text
for i, v in enumerate(fires):
ax.text(v + 180, i, f'{v:,}'.replace(',', '.'), color='#08519c', fontweight='normal', ha='left', va='center')
plt.subplots_adjust(left=0.22) # more space to read the names
plt.title('Wildfires Brazil 2019', fontsize=20, y=0.98) # title larger and a bit lower
plt.show()
PS: about
for i, v in enumerate(fires):
ax.text(v + 180, i, f'{v:,}'.replace(',', '.'), color='#08519c', fontweight='normal', ha='left', va='center')
This has a v going through each element of fires, one by one. i is the index for which fires[i] == b. ax.text(x, y, 'some text') puts a text on a certain position, where they are measured with the same distances as those marked on the axes (that's why default the axes are shown). When the axes are just text instead of numbers, they are numbered internally 0, 1, 2, 3, ... . So, x=v + 180 is the x-position where number-of-fires v+180 would be. And y=i means just the position of label number i.
So I've been trying to plot some data. I have got the data to fetch from a database and placed it all correctly into the variable text_. This is the snippet of the code:
import sqlite3
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from dateutil.parser import parse
fig, ax = plt.subplots()
# Twin the x-axis twice to make independent y-axes.
axes = [ax, ax.twinx(), ax.twinx()]
# Make some space on the right side for the extra y-axis.
fig.subplots_adjust(right=0.75)
# Move the last y-axis spine over to the right by 20% of the width of the axes
axes[-1].spines['right'].set_position(('axes', 1.2))
# To make the border of the right-most axis visible, we need to turn the frame on. This hides the other plots, however, so we need to turn its fill off.
axes[-1].set_frame_on(True)
axes[-1].patch.set_visible(False)
# And finally we get to plot things...
text_ = [('01/08/2017', 6.5, 143, 88, 60.2, 3), ('02/08/2017', 7.0, 146, 90, 60.2, 4),
('03/08/2017', 6.7, 142, 85, 60.2, 5), ('04/08/2017', 6.9, 144, 86, 60.1, 6),
('05/08/2017', 6.8, 144, 88, 60.2, 7), ('06/08/2017', 6.7, 147, 89, 60.2, 8)]
colors = ('Green', 'Red', 'Blue')
label = ('Blood Sugar Level (mmol/L)', 'Systolic Blood Pressure (mm Hg)', 'Diastolic Blood Pressure (mm Hg)')
y_axisG = [text_[0][1], text_[1][1], text_[2][1], text_[3][1], text_[4][1], text_[5][1]] #Glucose data
y_axisS = [text_[0][2], text_[1][2], text_[2][2], text_[3][2], text_[4][2], text_[5][2]] # Systolic Blood Pressure data
y_axisD = [text_[0][3], text_[1][3], text_[2][3], text_[3][3], text_[4][3], text_[5][3]] # Diastolic Blood Pressure data
AllyData = [y_axisG, y_axisS, y_axisD] #list of the lists of data
dates = [text_[0][0], text_[1][0], text_[2][0], text_[3][0], text_[4][0], text_[5][0]] # the dates as strings
x_axis = [(parse(x, dayfirst=True)) for x in dates] #converting the dates to datetime format for the graph
Blimits = [5.5, 130, 70] #lower limits of the axis
Tlimits = [8, 160, 100] #upper limits of the axis
for ax, color, label, AllyData, Blimits, Tlimits in zip(axes, colors, label, AllyData, Blimits, Tlimits):
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%m/%d/%Y')) #format's the date
plt.gca().xaxis.set_major_locator(mdates.DayLocator())
data = AllyData
ax.plot(data, color=color) #plots all the y-axis'
ax.set_ylim([Blimits, Tlimits]) #limits
ax.set_ylabel(label, color=color) #y-axis labels
ax.tick_params(axis='y', colors=color)
axes[0].set_xlabel('Date', labelpad=20)
plt.gca().set_title("Last 6 Month's Readings",weight='bold',fontsize=15)
plt.show()
The code currently makes this graph:
Graph with no x-values
I understand the problem is probably in the ax.plot part but I'm not sure what exactly. I tried putting that line of code as ax.plot(data, x_axis, color=color however, this made the whole graph all messed up and the dates didn't show up on the x-axis like i wanted them to.
Is there something I've missed?
If this has been answered elsewhere, please can you show me how to implement that into my code by editing my code?
Thanks a ton
Apparently x_data is never actually used in the code. Instead of
ax.plot(data, color=color)
which plots the data against its indices, you would want to plot the data against the dates stored in x_axis.
ax.plot(x_axis, data, color=color)
Finally, adding plt.gcf().autofmt_xdate() just before plt.show will rotate the dates nicely, such that they don't overlap.
I'm beginner for Python. I believe Python will do this task for 3D contour map.
I have data such as below
Y/X (mm), 0, 10, 20, 30, 40
686.6, -5.02, -0.417, 0, 100.627, 0
694.08, -5.02, -4.529, -17.731, -5.309, -3.535
701.56, 1.869, -4.529, -17.731, -5.309, -3.535
709.04, 1.869, -4.689, -17.667, -5.704, -3.482
716.52, 4.572, -4.689, -17.186, -5.704, -2.51
724, 4.572, -4.486, -17.186, -5.138, -2.51
731.48, 6.323, -4.486, -16.396, -5.138, -1.933
738.96, 6.323, -4.977, -16.396, -5.319, -1.933
746.44, 7.007, -4.251, -16.577, -5.319, -1.688
753.92, 7.007, -4.251, -16.577, -5.618, -1.688
761.4, 7.338, -3.514, -16.78, -5.618, -1.207
768.88, 7.338, -3.514, -16.78, -4.657, -1.207
776.36, 7.263, -3.877, -15.99, -4.657, -0.822
Any help How to start..
Update Question
(1) As you can see the raw data, they has xlabel and ylabel in respectively 1st row, 1st column.
If I use numpy.loadtxt function, How to split "xs" and "ys" ?
data = numpy.loadtxt('131014-data-xy-conv-1.txt')
(2) Do you have ay idea to rotate the matrix M x N from ?
(3) linespace has start = -70 and stop = 60, and num= 60, Do you have any idea how to make a step 5 ?
contour = subplot.contourf(xs, ys, data, levels=numpy.linspace(-70, 60, 60))
You can use matplotlib, namely its contourf function:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy
xs = numpy.array([0, 10, 20, 30, 40])
ys = numpy.array([686.6, 694.08, 701.56, 709.04, 716.52,
724, 731.48, 738.96, 746.44, 753.92, 761.4, 768.88, 776.36])
data = numpy.array([
[-5.02, -0.417, 0, 100.627, 0],
[-5.02, -4.529, -17.731, -5.309, -3.535],
[1.869, -4.529, -17.731, -5.309, -3.535],
[1.869, -4.689, -17.667, -5.704, -3.482],
[4.572, -4.689, -17.186, -5.704, -2.51],
[4.572, -4.486, -17.186, -5.138, -2.51],
[6.323, -4.486, -16.396, -5.138, -1.933],
[6.323, -4.977, -16.396, -5.319, -1.933],
[7.007, -4.251, -16.577, -5.319, -1.688],
[7.007, -4.251, -16.577, -5.618, -1.688],
[7.338, -3.514, -16.78, -5.618, -1.207],
[7.338, -3.514, -16.78, -4.657, -1.207],
[7.263, -3.877, -15.99, -4.657, -0.822]])
fig = plt.figure()
subplot = fig.add_subplot(111, xlabel='$x$, mm', ylabel='$y$, mm')
contour = subplot.contourf(xs, ys, data, levels=numpy.linspace(-20, 120, 20))
subplot.set_xlim((xs[0], xs[-1]))
subplot.set_ylim((ys[0], ys[-1]))
fig.colorbar(contour)
fig.savefig('t.png')
You can see what's matplotlib is capable of here.
how do I plot an area around a set of points on a map in R? e.g.
map('world')
map.axes()
p <- matrix(c(50, 50, 80, 100, 70, 40, 25, 60), ncol=2) # make some points
points(p, pch=19, col="red")
polygon(p, col="blue")
... which gives me a polygon with a vertex at each of the points, but it looks rather crappy. Is there any way to "smooth" the polygon into some sort of curve?
One option is to make a polygon bounded by a Bézier curve, using the bezier function in the Hmisc package. However I cannot get the start/end point to join up neatly. For example:
## make some points
p <- matrix(c(50, 50, 80, 100, 70, 40, 25, 60), ncol=2)
## add the starting point to the end
p2 <- cbind(1:5,p[c(1:4,1),])
## linear interpolation between these points
t.coarse <- seq(1,5,0.05)
x.coarse <- approx(p2[,1],p2[,2],xout=t.coarse)$y
y.coarse <- approx(p2[,1],p2[,3],xout=t.coarse)$y
## create a Bezier curve
library(Hmisc)
bz <- bezier(x.coarse,y.coarse)
library(maps)
map('world')
map.axes()
polygon(bz$x,bz$y, col=rgb(0,0,1,0.5),border=NA)
Here's one way, draw the polygon and make it as pretty as you like. This really has nothing to do with areas on maps, more about how you generate the vertices of your polygon.
library(maps)
p <- matrix(c(50, 50, 80, 100, 70, 40, 25, 60), ncol=2)
plot(p, pch = 16, col = "red", cex = 3, xlim = range(p[,1]) + c(-10,10), ylim = range(p[,2]) + c(-5, 5))
map(add = TRUE)
#click until happy, right-click "stop" to finish
p <- locator(type = "l")
map()
polygon(cbind(p$x, p$y), col = "blue")
Otherwise you could interpolate intermediate vertices and smooth them somehow, and in the context of a lon/lat map maybe with use reprojection to get more realistic line segments - but depends on your purpose.