I'm struggling a bit to get the secondary axis the way I want.
Here is the data:
structure(list(date = structure(c(19723, 19724, 19725, 19726,
19727, 19728, 19729, 19730, 19731, 19732, 19733, 19734, 19735,
19736, 19737, 19738, 19739, 19740, 19741, 19742, 19743, 19744,
19745, 19746, 19747, 19748, 19749, 19750, 19751, 19752, 19753,
19754, 19755, 19756, 19757, 19758, 19759, 19760, 19761, 19762,
19763, 19764, 19765), class = "Date"), tmin = c(3.8, 2.8, 8.1,
8.2, 4.6, 3.6, 1.8, -0.8, 4.1, 4.7, 2.3, -0.4, 2.2, 5.8, 8.4,
11.1, 10, 10, 3.6, 2.7, 4, 3.1, 4.4, 5.9, 5.9, 5.9, 9.6, 8, 7.7,
5.9, 4.7, 4.6, 5.2, 5.9, 4.6, 4.6, 5.9, NA, 8.5, 7.9, 5.3, 4.3,
6), tmax = c(9.4, 8.2, 12.1, 10.6, 8.6, 9.6, 9.3, 6.2, 7.2, 8,
7.6, 6.9, 9, 8.6, 13.3, 13.7, 12.3, 14.3, 10.8, 9.9, 11, 10.6,
14.9, 17.5, 17.3, 18.8, 18, 16.3, 14.9, 13, 10.5, 16.8, 14.8,
15.2, 16.6, 14.9, 13.7, NA, 12.6, 11.7, 11.3, 8.3, 15.7), tmean = c(6.6,
5.5, 10.1, 9.4, 6.6, 6.6, 5.6, 2.7, 5.6, 6.4, 5, 3.2, 5.6, 7.2,
10.8, 12.4, 11.2, 12.2, 7.2, 6.3, 7.5, 6.8, 9.6, 11.7, 11.6,
12.4, 13.8, 12.2, 11.3, 9.4, 7.6, 10.7, 10, 10.6, 10.6, 9.8,
9.8, NA, 10.6, 9.8, 8.3, 6.3, 10.8), pcp = c(NA, 2, 2.7, 9.7,
0.1, NA, NA, NA, NA, 0.2, NA, NA, NA, 4.3, 2.6, 7.5, 1.1, 12.4,
16.3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, 6.2, 6.5, 0.4, 0.1, NA)), row.names = c(NA,
-43L), class = c("tbl_df", "tbl", "data.frame"))
And here is my code so far:
selected_year <- 2024
ggplot2::ggplot(data = plot_data, aes(x = date)) +
ggplot2::geom_col(aes(y = pcp, fill = "pcp"), na.rm = TRUE) +
ggplot2::geom_line(aes(y = tmean, color = "tmean")) +
ggplot2::geom_line(aes(y = tmax, color = "tmax")) +
ggplot2::geom_line(aes(y = tmin, color = "tmin")) +
ggplot2::scale_fill_manual(
values = c("pcp" = "#2c7bb6"),
label = paste0("Daily pcp."), guide = guide_legend(order = 1)) +
ggplot2::scale_color_manual(
values = c("tmean" = "black", "tmin" = "blue", "tmax" = "red"),
label = c("tmean" = "Daily mean temp.", "tmin" = "Daily min temp.", "tmax" = "Daily max temp.")) +
ggplot2::scale_y_continuous(
labels = function(x) paste0(x, "ºC"),
breaks = round(seq(from = round(min(plot_data$tmin, na.rm = TRUE) - 5),
to = 45, by = 5) / 5) * 5,
limits = c(min(plot_data$tmin, na.rm = TRUE) - 5, 45),
sec.axis = sec_axis(trans = ~., labels = function(x) paste0(x, "mm"))
) +
ggplot2::scale_x_continuous(
breaks = as.numeric(seq(ymd(paste0(selected_year, "-01-15")),
ymd(paste0(selected_year, "-12-31")), by = "month")),
labels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"),
limits = c(as.numeric(ymd(paste0(selected_year, "-01-01"))),
as.numeric(ymd(paste0(selected_year, "-12-31"))))) +
ggthemes::theme_hc(base_size = 15) +
ggplot2::labs(
x = "", y = "", title = paste0("Precipitation and temperature in Madrid - Retiro ", selected_year),
subtitle = paste0("Daily precipitation and daily mean, max and min temperatures")) +
ggplot2::theme(
plot.title = ggplot2::element_text(hjust = 1, face = "bold", family = "sans", size = 35),
plot.subtitle = ggplot2::element_text(hjust = 1, size = 25),
legend.background = ggplot2::element_blank(),
legend.box.background = ggplot2::element_rect(fill = "white", color = "black", linewidth = 0.75),
legend.position = c(0.1335, 0.8),
legend.spacing = ggplot2::unit(0, "cm"),
legend.margin = ggplot2::margin(r = 5, l = 5, b = 5),
legend.title = element_blank())
The code draws the following plot:
What I want is to draw the bars for precipitation starting at the minimum temperature showed on the label for the primary axis (temperature). In this particular case, precipitation bars should start at -5ºC. However, this might change depending on data, as some locations may have different minimum temperatures across the year.
Minimum temperature label will always be (round(seq(from = round(min(plot_data$tmin, na.rm = TRUE) - 5), to = 45, by = 5) / 5) * 5)[1]
EDIT:
With this other data
structure(list(date = structure(c(19358, 19359, 19360, 19361,
19362, 19363, 19364, 19365, 19366, 19367, 19368, 19369, 19370,
19371, 19372, 19373, 19374, 19375, 19376, 19377, 19378, 19379,
19380, 19381, 19382, 19383, 19384, 19385, 19386, 19387, 19388,
19389, 19390, 19391, 19392, 19393, 19394, 19395, 19396, 19397,
19398, 19399, 19400, 19401, 19402, 19403, 19404, 19405, 19406,
19407, 19408, 19409, 19410, 19411, 19412, 19413, 19414, 19415,
19416, 19417, 19418, 19419, 19420, 19421, 19422, 19423, 19424,
19425, 19426, 19427, 19428, 19429, 19430, 19431, 19432, 19433,
19434, 19435, 19436, 19437, 19438, 19439, 19440, 19441, 19442,
19443, 19444, 19445, 19446, 19447, 19448, 19449, 19450, 19451,
19452, 19453, 19454, 19455, 19456, 19457, 19458, 19459, 19460,
19461, 19462, 19463, 19464, 19465, 19466, 19467, 19468, 19469,
19470, 19471, 19472, 19473, 19474, 19475, 19476, 19477, 19478,
19479, 19480, 19481, 19482, 19483, 19484, 19485, 19486, 19487,
19488, 19489, 19490, 19491, 19492, 19493, 19494, 19495, 19496,
19497, 19498, 19499, 19500, 19501, 19502, 19503, 19504, 19505,
19506, 19507, 19508, 19509, 19510, 19511, 19512, 19513, 19514,
19515, 19516, 19517, 19518, 19519, 19520, 19521, 19522, 19523,
19524, 19525, 19526, 19527, 19528, 19529, 19530, 19531, 19532,
19533, 19534, 19535, 19536, 19537, 19538, 19539, 19540, 19541,
19542, 19543, 19544, 19545, 19546, 19547, 19548, 19549, 19550,
19551, 19552, 19553, 19554, 19555, 19556, 19557, 19558, 19559,
19560, 19561, 19562, 19563, 19564, 19565, 19566, 19567, 19568,
19569, 19570, 19571, 19572, 19573, 19574, 19575, 19576, 19577,
19578, 19579, 19580, 19581, 19582, 19583, 19584, 19585, 19586,
19587, 19588, 19589, 19590, 19591, 19592, 19593, 19594, 19595,
19596, 19597, 19598, 19599, 19600, 19601, 19602, 19603, 19604,
19605, 19606, 19607, 19608, 19609, 19610, 19611, 19612, 19613,
19614, 19615, 19616, 19617, 19618, 19619, 19620, 19621, 19622,
19623, 19624, 19625, 19626, 19627, 19628, 19629, 19630, 19631,
19632, 19633, 19634, 19635, 19636, 19637, 19638, 19639, 19640,
19641, 19642, 19643, 19644, 19645, 19646, 19647, 19648, 19649,
19650, 19651, 19652, 19653, 19654, 19655, 19656, 19657, 19658,
19659, 19660, 19661, 19662, 19663, 19664, 19665, 19666, 19667,
19668, 19669, 19670, 19671, 19672, 19673, 19674, 19675, 19676,
19677, 19678, 19679, 19680, 19681, 19682, 19683, 19684, 19685,
19686, 19687, 19688, 19689, 19690, 19691, 19692, 19693, 19694,
19695, 19696, 19697, 19698, 19699, 19700, 19701, 19702, 19703,
19704, 19705, 19706, 19707, 19708, 19709, 19710, 19711, 19712,
19713, 19714, 19715, 19716, 19717, 19718, 19719, 19720, 19721,
19722), class = "Date"), tmin = c(7.8, 9, 5.9, 3.1, 3, 1.9, 2.5,
7.7, 5.9, 3.4, 4.9, 1.7, 3.7, 1.8, 4.3, 2.9, 2.8, 2.1, 1.2, 6.6,
3.4, 0.2, -1.8, 0.2, 0.3, -0.2, -1, -0.6, -1.6, -1.1, -1.6, 1.8,
2.4, 0.8, 1.1, 4.5, 2.3, 2.8, 2.3, 4.2, 2, 1.3, 1.9, 2.3, 4.3,
5.8, 3.8, 3.4, 5.8, 7.9, 9.1, 8.6, 5.9, 2.7, -0.3, 0.1, 0.1,
0.4, -1.8, -1.6, -1.6, 0.1, 1.4, 2.3, 4.5, 8.5, 9.5, 10.9, 8.6,
8.9, 9.8, 10.1, 7.2, 7, 9.3, 10.4, 6.5, 7.6, 7, 8.1, 8.6, 8.3,
9.9, 8.4, 9.5, 7.2, 8.3, 10.6, 11.5, 11.2, 10.3, 5.8, 5.1, 8.3,
5.7, 9.1, 9.2, 9.3, 10.6, 11.9, 11.3, 10, 6.9, 8.9, 10.1, 10.5,
10.7, 8.9, 10.4, 11.6, 12.1, 12, 9.1, 11.6, 13.3, 13.5, 15.7,
18.7, 16.3, 14.1, 12.1, 13.5, 16.2, 14.8, 12.2, 13.5, 16.1, 14.5,
17.2, 13.1, 10, 10, 8.4, 9.2, 8.6, 9.7, 8.3, 9.6, 9.7, 8.8, 11.1,
13.6, 13.5, 13.4, 13.5, 12.1, 13.3, 12.4, 12.4, 12.4, 12.6, 13.5,
13.5, 13.4, 15.2, 16.1, 15.5, 15.8, 15.9, 14.6, 16.3, 16.9, 17.1,
15.1, 15.6, 17.9, 19.9, 20.9, 20.3, 18.5, 19.2, 16.2, 15.4, 19.6,
21.1, 23.1, 22.3, 22.3, 22.9, 19.6, 16.7, 17.9, 20.2, 22.3, 20.5,
21.3, 21.6, 21.4, 19.7, 19.3, 21.5, 23.6, 21.3, 21.4, 22.8, 21.1,
20.4, 22.2, 25, 25.3, 20.9, 20.7, 19.3, 19.8, 19.2, 17.4, 18.1,
21.2, 19.8, 21, 22.4, 23.4, 21.2, 22.1, 20.9, 15.8, 15.6, 20.1,
19, 22.6, 24.2, 22.8, 23.5, 23.4, 23.4, 22.3, 20.3, 19.9, 20.9,
20.6, 21.3, 21.8, 25, 24.7, 25.7, 24.1, 22.9, 19.9, 16.1, 15.1,
17.1, 16.2, 17.4, 18.4, 15.4, 15.4, 16.1, 16.7, 18.1, 19.9, 20.3,
19.3, 18.5, 17.1, 17.5, 16.5, 18.4, 15.5, 16, 14.9, 14.5, 13.6,
13.5, 14.4, 11.7, 10.7, 12.7, 13.5, 15.6, 16.1, 15.4, 15.7, 18.4,
18.1, 17.4, 17.1, 17.3, 17.4, 18, 18.2, 17, 16.7, 16, 15.2, 13.7,
15.9, 14.9, 13.5, 14.9, 15.7, 15.6, 10.9, 10.5, 7.8, 10.2, 10.2,
9.1, 11.8, 11.6, 9.3, 11.7, 12.5, 8.7, 7.5, 8.3, 7.1, 7.1, 9.7,
8.5, 5.2, 3.4, 4.9, 9.6, 7.9, 11.5, 11.9, 11.6, 10.3, 10.5, 10.8,
10.9, 8.3, 8.3, 7.6, 7.5, 7.1, 3, 3.1, 3.3, 4.9, 5.2, 7.1, 11,
12.1, 5.8, 4.1, 1.8, 4.9, 4.9, 2.9, 3.6, 5.9, 5.8, 10.4, 9, 7.7,
6.6, 2.6, 4.8, 2, 1.9, 1.3, 1.1, 1.8, 2.2, 2.2, 2.5, 1.9, 0.7,
0.4, -0.2, 0.9, 3.7, 1.8, 5), tmax = c(14.8, 11.8, 12.1, 11.6,
11.6, 10.5, 7.9, 13.2, 12.7, 10.5, 9.2, 10.6, 11.1, 10.3, 11.2,
10.1, 9.9, 5.9, 7.7, 13.7, 9.8, 8.4, 8.5, 5.7, 9.1, 9.2, 8.6,
9.3, 5.9, 8.2, 10.9, 11.8, 12.7, 15.2, 17, 16.2, 10.8, 8.4, 9.9,
10.3, 9, 10.4, 11.2, 10, 10.3, 12.5, 14.1, 14.8, 14.3, 17.8,
19, 17.5, 15.7, 9.6, 9.7, 9.8, 11.4, 6.7, 8.9, 6.2, 9.9, 11.9,
12.4, 10.3, 13.4, 15.5, 15.8, 17.2, 18.7, 19.8, 20.6, 19.9, 17.2,
19.3, 22.8, 16.5, 15.6, 18, 19.8, 20.9, 21.6, 21.2, 19, 20.7,
20.7, 19.9, 22.9, 25.2, 22, 20.9, 19.1, 18.5, 19.3, 20.7, 21.1,
23.3, 24.2, 26, 26.5, 26.2, 25.9, 20, 15.9, 19.3, 23.3, 24, 25.1,
22.9, 23.8, 27, 25.5, 20.5, 23.3, 25.1, 27.8, 28.9, 30.7, 30.9,
25.5, 24.2, 26.6, 27.9, 29.1, 25.4, 26.5, 28, 27, 29, 27.1, 24.9,
22.8, 19.4, 20.7, 20.6, 21.7, 22.4, 23.8, 22.6, 21.8, 20.5, 21.5,
23.9, 25.2, 25.1, 25.1, 17.9, 21.5, 18.5, 23.5, 23.2, 25.2, 25.1,
24.1, 25.3, 26.6, 28, 28.5, 22, 20.3, 24.1, 26.8, 27.9, 28.3,
24.4, 27, 30.4, 32.5, 34, 30.8, 29.9, 27.4, 28.3, 29, 32.2, 34.2,
37, 37, 34.9, 34.9, 36.6, 29.3, 31.7, 34.7, 35.1, 33.5, 33, 33.7,
34.2, 32.7, 34.2, 37.8, 38, 33.2, 35.1, 36.8, 32.3, 34, 38.7,
38.5, 37.5, 36.4, 31.9, 31.7, 36.3, 32.5, 31.9, 32.9, 34.2, 34,
36.6, 36.8, 36.6, 36.6, 35.7, 32.8, 29, 33, 36.3, 36.5, 37.8,
39.5, 38, 38.8, 37.9, 37.8, 36.2, 36.6, 36.3, 36.2, 34.4, 36.7,
38, 40, 39.7, 38.9, 39, 37.8, 31.5, 23.8, 27.2, 28.9, 27.8, 31.4,
31.6, 23.2, 20.9, 23.3, 27.3, 27.6, 29, 29.4, 27.4, 28.9, 26,
27, 27.3, 26.7, 24.3, 22.2, 19.2, 20, 23.2, 23.9, 18.6, 20.5,
22.2, 25.3, 27.8, 27, 27.1, 28.2, 29.9, 29.2, 30, 29, 29, 26.8,
29.2, 30.1, 29, 29, 27.5, 26.4, 26.3, 26.7, 25.3, 21.2, 21.1,
20, 23.2, 20.6, 16.7, 15.8, 16.2, 15.5, 14.8, 13.2, 17.2, 18.2,
15, 16.6, 16.3, 15.9, 12.6, 14.3, 15.9, 13.1, 13.9, 13.4, 12.9,
10.1, 11.5, 15.5, 14.6, 17.6, 18.6, 18, 15.8, 15.7, 13.7, 16.1,
17.1, 17.5, 17.3, 13.2, 13.5, 13.7, 14.8, 15.5, 13.2, 10.8, 12,
13.7, 14.6, 12.5, 10, 7.5, 10.1, 8.1, 9.1, 8.6, 11.6, 12.7, 12.1,
12.8, 12.1, 11.3, 11.1, 13.1, 11.1, 11.4, 11, 10.9, 11.9, 11.6,
13.1, 12.6, 10.8, 9.7, 8.3, 9.3, 7.1, 8.5, 10.7, 9.4), tmean = c(11.3,
10.4, 9, 7.4, 7.3, 6.2, 5.2, 10.4, 9.3, 7, 7, 6.2, 7.4, 6, 7.8,
6.5, 6.4, 4, 4.4, 10.2, 6.6, 4.3, 3.4, 3, 4.7, 4.5, 3.8, 4.4,
2.2, 3.6, 4.6, 6.8, 7.6, 8, 9, 10.4, 6.6, 5.6, 6.1, 7.2, 5.5,
5.8, 6.6, 6.2, 7.3, 9.2, 9, 9.1, 10, 12.8, 14, 13, 10.8, 6.2,
4.7, 5, 5.8, 3.6, 3.6, 2.3, 4.2, 6, 6.9, 6.3, 9, 12, 12.6, 14,
13.6, 14.4, 15.2, 15, 12.2, 13.2, 16, 13.4, 11, 12.8, 13.4, 14.5,
15.1, 14.8, 14.4, 14.6, 15.1, 13.6, 15.6, 17.9, 16.8, 16, 14.7,
12.2, 12.2, 14.5, 13.4, 16.2, 16.7, 17.6, 18.6, 19, 18.6, 15,
11.4, 14.1, 16.7, 17.2, 17.9, 15.9, 17.1, 19.3, 18.8, 16.2, 16.2,
18.4, 20.6, 21.2, 23.2, 24.8, 20.9, 19.2, 19.4, 20.7, 22.6, 20.1,
19.4, 20.8, 21.6, 21.8, 22.2, 19, 16.4, 14.7, 14.6, 14.9, 15.2,
16, 16, 16.1, 15.8, 14.6, 16.3, 18.8, 19.4, 19.2, 19.3, 15, 17.4,
15.4, 18, 17.8, 18.9, 19.3, 18.8, 19.4, 20.9, 22, 22, 18.9, 18.1,
19.4, 21.6, 22.4, 22.7, 19.8, 21.3, 24.2, 26.2, 27.4, 25.6, 24.2,
23.3, 22.2, 22.2, 25.9, 27.6, 30, 29.6, 28.6, 28.9, 28.1, 23,
24.8, 27.4, 28.7, 27, 27.2, 27.6, 27.8, 26.2, 26.8, 29.6, 30.8,
27.2, 28.2, 29.8, 26.7, 27.2, 30.4, 31.8, 31.4, 28.6, 26.3, 25.5,
28, 25.8, 24.6, 25.5, 27.7, 26.9, 28.8, 29.6, 30, 28.9, 28.9,
26.8, 22.4, 24.3, 28.2, 27.8, 30.2, 31.8, 30.4, 31.2, 30.6, 30.6,
29.2, 28.4, 28.1, 28.6, 27.5, 29, 29.9, 32.5, 32.2, 32.3, 31.6,
30.4, 25.7, 20, 21.2, 23, 22, 24.4, 25, 19.3, 18.2, 19.7, 22,
22.8, 24.4, 24.8, 23.4, 23.7, 21.6, 22.2, 21.9, 22.6, 19.9, 19.1,
17, 17.2, 18.4, 18.7, 16.5, 16.1, 16.4, 19, 20.6, 21.3, 21.6,
21.8, 22.8, 23.8, 24, 23.2, 23, 22, 23.3, 24, 23.6, 23, 22.1,
21.2, 20.8, 20.2, 20.6, 18, 17.3, 17.4, 19.4, 18.1, 13.8, 13.2,
12, 12.8, 12.5, 11.2, 14.5, 14.9, 12.2, 14.2, 14.4, 12.3, 10,
11.3, 11.5, 10.1, 11.8, 11, 9, 6.8, 8.2, 12.6, 11.2, 14.6, 15.2,
14.8, 13, 13.1, 12.2, 13.5, 12.7, 12.9, 12.4, 10.4, 10.3, 8.4,
9, 9.4, 9, 8, 9.6, 12.4, 13.4, 9.2, 7, 4.6, 7.5, 6.5, 6, 6.1,
8.8, 9.2, 11.2, 10.9, 9.9, 9, 6.8, 9, 6.6, 6.6, 6.2, 6, 6.8,
6.9, 7.6, 7.6, 6.4, 5.2, 4.4, 4.6, 4, 6.1, 6.2, 7.2), pcp = c(0.1,
NA, NA, NA, NA, NA, 6.3, 4.2, NA, NA, 0.1, NA, NA, NA, NA, 0.4,
0.2, NA, 0.3, NA, NA, NA, NA, NA, 0.1, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, 1.1, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.4, 0.1, NA, NA, NA, NA,
NA, NA, 4.2, 0.5, 1.8, 14.3, 1.1, 0.1, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, 7.3, 0.5, NA, NA, NA, NA, NA, NA, 0.5, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1.5, NA, NA, NA,
NA, NA, NA, 0.9, 0.7, 4.8, NA, 18.8, 6.3, 10.4, 7.4, 7.2, 0.6,
NA, 8.3, 1, 0.2, NA, 4.5, 2.9, 9.8, 3.3, NA, NA, NA, 1.8, 0.1,
NA, NA, NA, NA, 2.6, 0.5, NA, 7.5, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, 31.2, 66.5, 9.1, 6.2, NA, NA, 2.8, 3.6, 7.6, NA, NA, NA,
18.2, 13.3, 0.3, 6.3, NA, NA, NA, 0.7, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 2.4,
NA, 2.9, 0.8, 2.4, 6.8, 107.8, NA, NA, 41.2, 2.2, 1.8, NA, 3.9,
NA, 2, 6.1, 0.3, NA, 1.4, 17.9, 1, 1.5, NA, NA, 0.3, 0.9, NA,
2.1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, 0.1, NA, NA, NA, NA, NA, NA, NA, 14.2, NA, NA,
0.1, NA, 3.4, NA, NA, NA, NA, NA, NA, 0.2, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA)), row.names = c(NA, -365L), class = c("tbl_df",
"tbl", "data.frame"))
And using @L Tyrone's answer I'm getting the following plot:
Where you can see right axis for precipitation is messed up. The only modification I tried to do was to define l.y.max
and r.y.min
not as a fixed value but a dynamic value that changes with data:
l.y.max <- round((max(plot_data$pcp, na.rm = TRUE) + 10) / 5) * 5
r.y.min <- round((min(plot_data$tmin, na.rm = TRUE) - 5) / 5) * 5
The challenge arises when plotting two ranges of values and one is positve-only, and the other is both positive and negative. Here's a possible solution. It involves scaling your temperature values relative to your precipitation values prior to plotting. I find making nicely aligned axes ticks and labels easier with this method.
I have arbitrarily set the ymin/ymax values of each y-axis based on your sample data. Given you are likely to be creating multiple plots with potentially different ranges, it makes sense to have a fixed y-axis values to allow 'fair' comparisons between plots.
However, there's nothing stopping you modifying the y-axes limits based on your "minimum temperature" formula. If you do, you'll need to change the l.y.min
, l.y.max
, r.y.min
, and r.y.max
values accordingly. But the other advantage of the limit values used in this example is that the y-axes ticks and labels line up 'tidily'. If you choose custom limits, you may have to adjust the number of breaks in order to get nicely aligned ticks.
library(dplyr)
library(lubridate)
library(ggplot2)
# Your data
plot_data <- structure(list(date = structure(c(19723, 19724, 19725, 19726,
19727, 19728, 19729, 19730, 19731, 19732, 19733, 19734, 19735,
19736, 19737, 19738, 19739, 19740, 19741, 19742, 19743, 19744,
19745, 19746, 19747, 19748, 19749, 19750, 19751, 19752, 19753,
19754, 19755, 19756, 19757, 19758, 19759, 19760, 19761, 19762,
19763, 19764, 19765), class = "Date"), tmin = c(3.8, 2.8, 8.1,
8.2, 4.6, 3.6, 1.8, -0.8, 4.1, 4.7, 2.3, -0.4, 2.2, 5.8, 8.4,
11.1, 10, 10, 3.6, 2.7, 4, 3.1, 4.4, 5.9, 5.9, 5.9, 9.6, 8, 7.7,
5.9, 4.7, 4.6, 5.2, 5.9, 4.6, 4.6, 5.9, NA, 8.5, 7.9, 5.3, 4.3,
6), tmax = c(9.4, 8.2, 12.1, 10.6, 8.6, 9.6, 9.3, 6.2, 7.2, 8,
7.6, 6.9, 9, 8.6, 13.3, 13.7, 12.3, 14.3, 10.8, 9.9, 11, 10.6,
14.9, 17.5, 17.3, 18.8, 18, 16.3, 14.9, 13, 10.5, 16.8, 14.8,
15.2, 16.6, 14.9, 13.7, NA, 12.6, 11.7, 11.3, 8.3, 15.7), tmean = c(6.6,
5.5, 10.1, 9.4, 6.6, 6.6, 5.6, 2.7, 5.6, 6.4, 5, 3.2, 5.6, 7.2,
10.8, 12.4, 11.2, 12.2, 7.2, 6.3, 7.5, 6.8, 9.6, 11.7, 11.6,
12.4, 13.8, 12.2, 11.3, 9.4, 7.6, 10.7, 10, 10.6, 10.6, 9.8,
9.8, NA, 10.6, 9.8, 8.3, 6.3, 10.8), pcp = c(NA, 2, 2.7, 9.7,
0.1, NA, NA, NA, NA, 0.2, NA, NA, NA, 4.3, 2.6, 7.5, 1.1, 12.4,
16.3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, 6.2, 6.5, 0.4, 0.1, NA)), row.names = c(NA,
-43L), class = c("tbl_df", "tbl", "data.frame"))
# Set min and max limits for left y-axis
l.y.min <- 0
l.y.max <- 40
# Set min and max limits for right y-axis
r.y.min <- -10
r.y.max <- 50
# Function to scale right y-axis values (temperature in this case)
axis_scaled <- function(x) {
y <- ifelse(is.na(x), NA,
((x - r.y.min) / (r.y.max - r.y.min)) *
(l.y.max - l.y.min) + l.y.min)
y <- y[2:(length(y)-1)]
}
# create copy of plot_data with scaled temperature values
plot_data1 <- plot_data %>%
mutate_at(vars(tmin:tmean), list(~ axis_scaled(c(r.y.min, ., r.y.max))))
# Create breaks for left and right y-axis, and labels for right y-axis
l.y.labels <- paste0(seq(r.y.min, r.y.max, 5), "ºC")
l.y.breaks <- seq(l.y.min, l.y.max, length.out = length(l.y.labels))
r.y.labels <- paste0(seq(l.y.min, l.y.max, 10), "mm")
r.y.breaks <- seq(l.y.min, l.y.max, length.out = length(r.y.labels))
selected_year <- 2024
# Plot
ggplot(data = plot_data1, aes(x = date)) +
geom_col(aes(y = pcp, fill = "pcp")) +
geom_line(aes(y = tmean, color = "tmean")) +
geom_line(aes(y = tmax, color = "tmax")) +
geom_line(aes(y = tmin, color = "tmin")) +
scale_fill_manual(
values = c("pcp" = "#2c7bb6"),
label = paste0("Daily pcp."), guide = guide_legend(order = 1)) +
scale_color_manual(
values = c("tmean" = "black", "tmin" = "blue", "tmax" = "red"),
label = c("tmean" = "Daily mean temp.", "tmin" = "Daily min temp.",
"tmax" = "Daily max temp.")) +
scale_y_continuous(breaks = l.y.breaks,
limits = c(l.y.min, l.y.max),
labels = l.y.labels,
sec.axis = sec_axis(~ .,
breaks = r.y.breaks,
labels = r.y.labels)) +
scale_x_continuous(
breaks = as.numeric(seq(ymd(paste0(selected_year, "-01-15")),
ymd(paste0(selected_year, "-12-31")), by = "month")),
labels = month.abb[], # Saves having to type out each individual month label
limits = c(as.numeric(ymd(paste0(selected_year, "-01-01"))),
as.numeric(ymd(paste0(selected_year, "-12-31"))))) +
ggthemes::theme_hc(base_size = 15) +
labs(
x = "",
y = "",
title = paste0("Precipitation and temperature in Madrid - Retiro ", selected_year),
subtitle = paste0("Daily precipitation and daily mean, max and min temperatures")) +
theme(
plot.title = element_text(hjust = 1, face = "bold", family = "sans", size = 14),
plot.subtitle = element_text(hjust = 1, size = 12),
legend.background = element_blank(),
legend.box.background = element_rect(fill = "white", color = "black", linewidth = 0.75),
legend.position = c(0.1335, 0.8),
legend.spacing = unit(0, "cm"),
legend.margin = margin(r = 5, l = 5, b = 5),
legend.title = element_blank())