0

I am trying to draw a line plot having two x variables in the x-axis with one continuous y variable in the y-axis. The count of x1 and x2 are different. The df looks like the following-

df <- structure(list(val = c(3817,2428,6160,6729,7151,7451,6272,7146,7063,6344,5465,6169,7315,6888,7167,6759,4903,6461,7010,7018,6920,3644,6541,31862,31186,28090,28488,29349,28284,25815,23529,20097,19945,22118), type = c("1wt", "1wt", "3wt", "3wt", "3wt", "5wt", "5wt", "7wt", "7wt", "7wt","10wt","10wt","10wt","15wt","15wt","20wt","20wt","25wt","25wt","25wt","30wt","30wt","30wt","20m","20m","15m","15m","15m","10m","10m","5m", "5m", "5m", "5m"), group = c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B")), row.names = c(NA, 34L), class = "data.frame")

where the x variables are-

x1 <- factor(df$type, levels = c("1wt", "3wt", "5wt", "7wt", "10wt", "15wt", "20wt", "25wt", "30wt")) and

x2 <- factor(df$type, levels = c("20m", "15m","10m","5m"))

I want to have separate lines for the x1 and x2 with different colors and legends as per the df$group at the x-axis with df$val at the y -axis. could you please help me doing this? Thanks in advance.

8
  • I tried replicating but x1 and x2 are NAs. please check your code again. Commented Dec 25, 2018 at 10:20
  • and please explain what type of plot are you trying to produce: scatter? histogram? bars? Commented Dec 25, 2018 at 10:21
  • I am trying to draw a line plot ... please post your plotting attempt. Commented Dec 25, 2018 at 18:43
  • It's unclear to me from the question what the goal is. If we're using df as provided, with some adaptation of type on the x-axis and val on the y-axis, the first two lines of df show two val numbers (3817 and 2428) associated with the same type (1wt). Do you want to show a vertical line here, or is something else intended? Commented Dec 25, 2018 at 19:21
  • @JonSpring I want to have a line plot where for both x1 and x2 would have their lines for total y, that is- within the val range in the y axis, all x (x1 &x2) will fall and probably they will intersect each other. Thank you. Commented Dec 25, 2018 at 20:00

1 Answer 1

1

EDIT: added below

Here's an approach that assumes the intent is to map the span of possible type values from group A against the span of possible values from group B.

Labeling could be added manually, but I don't think there's any simple way to use two categorical x axes together in one plot.

df2 <- df %>%
  mutate(x = case_when(type == "1wt" ~ 0,
                       type == "3wt" ~ 1,
                       type == "5wt" ~ 2,
                       type == "7wt" ~ 3,
                       type == "10wt" ~ 4,
                       type == "15wt" ~ 5,
                       type == "20wt" ~ 6,
                       type == "25wt" ~ 7,
                       type == "30wt" ~ 8,

                       type == "20m"  ~ 0/3 * 8,
                       type == "15m"  ~ 1/3 * 8,
                       type == "10m"  ~ 2/3 * 8,
                       type == "5m"   ~ 3/3 * 8))


ggplot(df2, aes(x, val, color = group, group = group)) + 
  geom_point() +
  geom_smooth(method = lm)

enter image description here

2nd approach

It sounds like the OP would like to use the type values numerically in some fashion. If they aren't intrinsically linked to each other in the way that's described, I suspect it will be misleading to plot them as if they are. (See here for a discussion of why this is trouble.)

That said, here's how you could do it. First, here's an approach that just uses the numeric portion of type as is. Note that "m", associated with group B, is on the bottom and "wt" is on the top, associated with group A, as in the example added in the OP comment below. I've added colors to the axes to clarify this. It's a little counterintuitive visually, since the points related to the top axis are on the bottom, and vice versa.

df2 <- df %>%
  # First, let's take the number used in "type" without adjustment
  mutate(x_unadj = parse_number(type))

ggplot(df2, aes(x_unadj, val, color = group, group = group)) + 
  geom_point() +
  geom_smooth(method = lm) + # Feel free to use other smoothing method, but
                             # not obvious to me what would be improvement.
  scale_x_continuous("m", sec.axis = sec_axis(~., name = "wt")) +
  theme(axis.text.x.bottom  = element_text(color = "#00BFC4"),
        axis.title.x.bottom = element_text(color = "#00BFC4"),
        axis.text.x.top     = element_text(color = "#F8766D"),
        axis.title.x.top    = element_text(color = "#F8766D"))

enter image description here

If this is not satisfactory, we might reverse the order of both axes using

scale_x_reverse("m", sec.axis = sec_axis(~., name = "wt")) +

enter image description here

Using ggplot 3.1.0 (from Oct 2018), I could not get the secondary x axis to shift in the opposite direction as the primary axis. This example from 2017 doesn't seem to work with this version any more. As of Dec 2018, there is a proposed fix being reviewed that is meant to address this.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @JonSpring for this. I did not get how you calculated the type == "15m" ~ 8/3, type == "10m" ~ 2*8/3, type == "5m" ~ 8 specifically dividing by 3 and again multiplying. This link (i.sstatic.net/nUCgb.png) is an example what I want to have with simple lines not actually the lm, if possible. Basically my aim is to plot x1 & x2 in respect to all df$val (that includes all values for group A & B- should range from min at the bottom to max at the top) in the y axis or they can be plotted as y1 and y2 on both sides may be. I really appreciate your time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.