7
$\begingroup$

I would like to create a graph similar to this below using some slightly dotted bar style like the one shown in the figure ...

enter image description here

And I'm trying to open a space between bars 6 and 8, but I'm failing.

Any idea?

g = Plot[3 - 1/2 x, {x, 0, 14}, PlotRange -> {{0, 14}, {-3, 3}}, 
   AspectRatio -> 0.5];
bar = BarChart[Table[3 - 1/2 x, {x, 2, 14, 2}]];
Show[bar, g]

enter image description here

$\endgroup$
1
  • $\begingroup$ Related (124392) $\endgroup$
    – Edmund
    Jul 8, 2017 at 0:59

2 Answers 2

6
$\begingroup$

You can also use RectangleChart with a custom ChartElementFunction:

ClearAll[ceF, rectChart]
ceF[func_][{{x0_, x1_}, {y0_, y1_}},  ___] := 
  Dynamic@{If[CurrentValue["Color"]=== White, {},
  {Texture[Rasterize[RandomImage[1, {50, 50}]]],
    Polygon[#, VertexTextureCoordinates -> #]&@{{x0, y0}, {x0, y1}, {x1, y1}, {x1, y0}}}], 
    Text[Style[Floor@x0, If[Floor@x0 == 0, White, Black], "Panel", 12], {x0, 0}, 
    Switch[Sign[func /@ {x0 - .01 Mean[{x0, x1}], x0 + .01 Mean[{x0, x1}]}], 
      {1, 1} | {1, -1} | {0, -1}, {0, 1}, {-1, -1} | {-1, 1} | {0, 1}, {0, -1}]]};

rectChart[fun_, from_, to_, o : OptionsPattern[]] := 
  RectangleChart[ArrayPad[Table[{from, fun[x]}, {x, from, to - 1, from}], {{1}}, 
     Style[{from, 1}, White]] /. x : {_, 0} :> Style[x + {0, 1}, White],
   BarSpacing -> 0, o, 
   Epilog -> (Plot[fun[x], {x, 0, to + from}, PlotStyle -> GrayLevel[.1]][[1]]), 
   PlotRange -> {fun[0], fun[to]}, ChartElementFunction -> ceF[fun]];

Examples:

f[x_] := 3 - x/2;
rectChart[f, 2, 14, ChartLegends -> 
  Placed[TraditionalForm[Style[HoldForm@f[x] == f[x], 16, "Panel"]], {.2, .3}]]

enter image description here

f[x_] := 3 - x/2;
rectChart[f, 1, 14, ChartLegends -> 
  Placed[TraditionalForm[Style[HoldForm@f[x] == f[x], 16, "Panel"]], {.2, .3}]]

enter image description here

rectChart[# Pi Cos[# Pi/4]/4 &, 2, 21, PlotRange -> {-20, 20}, 
  ChartLegends -> Placed[TraditionalForm[
    Style[HoldForm@f[x] == x Pi Cos[x Pi/4]/4, 16, "Panel"]], {.3, .9}]]

enter image description here

$\endgroup$
6
$\begingroup$

This is a bit easier to achieve with DiscretePlot instead of BarChart.

With

f[x_] := 3 - 1/2 x

Then

Show[
 Plot[f[x], {x, 0, 14}],
 DiscretePlot[f[x], {x, Range[2, 12, 2]}, 
  PlotMarkers -> "Point", 
  ExtentSize -> Right, 
  PlotStyle -> Gray],
 Epilog -> {
   Inset[Row[{Inactivate[f[x]], "=", f[x]}, Spacer[1]], 
    Scaled[{.2, .2}],
    FormatType -> TraditionalForm,
    BaseStyle -> {FontSize -> Scaled[.04]}]
   }
 ]

Mathematica graphics

Hope this helps.


Update

Taking cues from this answer (19542) and applying to a custom ExtentElementFunction can be created.

ClearAll[fillRandomDots];
fillRandomDots[{{xmin_, xmax_}, {ymin_, ymax_}}, ___] :=
 Module[{rect = Rectangle[{xmin, ymin}, {xmax, ymax}], dots, texture},
  If[ymax - ymin > 0,
   dots = RandomPoint[rect, Area@rect 600];
   texture =
    Rasterize@
     Graphics[{Opacity[.1, Gray], rect, 
       Opacity[.9, Lighter[Black, .3]], Disk[#, .05] & /@ dots},
      PlotRange -> {{xmin, xmax}, {ymin, ymax}},
      PlotRangePadding -> None,
      ImagePadding -> None
      ];
   ,
   texture = Graphics@{}
   ];
  {
   EdgeForm[{Thin, Black}],
   Texture@texture,
   Polygon[{{xmin, ymin}, {xmax, ymin}, {xmax, ymax}, {xmin, ymax}},
    VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]
   }
  ]

Then

Show[
 DiscretePlot[f[x], {x, Range[2, 12, 2]},
  PlotMarkers -> "Point",
  ExtentSize -> Right,
  ExtentElementFunction -> fillRandomDots],
 Plot[f[x], {x, 0, 14},
  PlotTheme -> "Monochrome"],
 PlotRange -> {{0, 14}, {-4, 3}},
 AxesOrigin -> {0, 0},
 Epilog -> {
   Inset[Row[{Inactivate[f[x]], "=", f[x]}, Spacer[1]], 
    Scaled[{.2, .2}],
    FormatType -> TraditionalForm,
    BaseStyle -> {FontSize -> Scaled[.04]}]
   }
 ]

Mathematica graphics

Cues can be taken from this answer (19542) to change the sides the axis ticks and labels appear.

$\endgroup$
4
  • $\begingroup$ Would I get this style punctuated as the photo I showed or could make the main purpose of the function difficult? $\endgroup$
    – LCarvalho
    Jul 8, 2017 at 2:13
  • 1
    $\begingroup$ @LCarvalho It can be done but would add some complexity. You would need to create a ExtentElementFunction for your custom fill in DiscretePlot (see 31221) and then do some post processing to flip the axis labels (see 6395). It would be more complicated but you could easily wrap it in a function once you were done. $\endgroup$
    – Edmund
    Jul 8, 2017 at 2:20
  • 1
    $\begingroup$ @LCarvalho See update. $\endgroup$
    – Edmund
    Jul 8, 2017 at 2:36
  • $\begingroup$ I'm voting for another answer because it's closer than I wanted. But your answer helped me a lot too. Thanks $\endgroup$
    – LCarvalho
    Jul 9, 2017 at 2:35

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.